Redux持久化无法持久化数组

5sxhfpxr  于 2023-03-18  发布在  其他
关注(0)|答案(1)|浏览(127)

我在我的react原生应用中使用Redux Perist。我的应用是一个资金管理器,因此用户可以存储支出和收入。因此,我希望有一个名为allEntries的数组,用于存储所有条目(支出或收入)。
我的EntriesOverview类,其中显示了所有条目。出于演示目的,我在goToAddNewEntryScreen()方法中添加了一个随机的新条目。

import React from 'react';
import {ColorPalette} from '../../Assets/Colors/ColorPalette';
import {Dimensions, Image, StyleSheet, Text, TouchableHighlight, View} from 'react-native';
import {addEntry} from '../../Redux/Actions/counterActions';
import {connect} from 'react-redux';

class EntriesOverviewScreen extends React.Component {

    state: {};
    styles = StyleSheet.create({
        btn_add: {
            position: 'absolute',
            right: 10,
            bottom: 10,
            backgroundColor: ColorPalette.lightMode.primary,
            color: ColorPalette.lightMode.white,
            borderRadius: Math.round(Dimensions.get('window').width + Dimensions.get('window').height) / 2,
            width: Dimensions.get('window').width * 0.15,
            height: Dimensions.get('window').width * 0.15,
            justifyContent: 'center',
            alignItems: 'center',
        },
        btn_add_icon: {
            width: '50%',
            height: '50%',
        },
        background_entries_overview: {
            backgroundColor: ColorPalette.lightMode.white,
            height: '100%',
        },

    });

    constructor(props: Props) {
        super(props);
        this.state = {};
    }

    render() {
        return (
            <View style={this.styles.background_entries_overview}>
                <Text>Entries overview</Text>
                <Text>{JSON.stringify(this.props.allEntries)}</Text>
                <TouchableHighlight
                    style={this.styles.btn_add}
                    onPress={() => this.goToAddNewEntryScreen()}>
                    <Image style={this.styles.btn_add_icon}
                           source={require('../../../MoneyMaster/Assets/Icons/plus_white.png')}/>
                </TouchableHighlight>
            </View>

        );
    }

    goToAddNewEntryScreen() {
        this.props.reduxAddEntry({
            id: -1,
            isExpense: true,
            amount: 0,
            date: new Date('2000-11-25'),
            note: '',
            reoccurring: 'asdf',
            categoryId: 0,
        });
        this.props.navigation.navigate('AddEntryScreen');
    }

}

// Map State To Props (Redux Store Passes State To Component)
const mapStateToProps = (state) => {
    // Redux Store --> Component
    return {
        allEntries: state.entriesReducer.allEntries,

    };
};

// Map Dispatch To Props (Dispatch Actions To Reducers. Reducers Then Modify The Data And Assign It To Your Props)
const mapDispatchToProps = (dispatch) => {
    // Action
    return {
        // Increase Counter
        reduxAddEntry: (entryToAdd) => dispatch(addEntry(entryToAdd)),
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(EntriesOverviewScreen);

我的counterAction

// Add an Entry
export const addEntry = (entryToAdd) => ({
  type: 'ADD_ENTRY',
  entryToAdd: entryToAdd
});

我的条目Reducer

// Initial State
const initialState = {
  allEntries:[],
  };


// Reducers (Modifies The State And Returns A New State)
const entriesReducer = (state = initialState, action) => {
  switch (action.type) {
    // Increase Counter
    case 'ADD_ENTRY': {
      let updatedAllEntries=state.allEntries.push(action.entryToAdd);
      return {
        // State
        ...state,
        // Redux Store
        allEntries: updatedAllEntries,
      }
    }
    // Default
    default: {
      return state;
    }
  }
};

// Exports
export default entriesReducer;

奇怪的是,当我调试它并第一次启动应用程序时,entriesReducer中的state.allEntries值总是1,尽管它应该是一个空数组。因此,我无法通过.push方法添加条目。我没有在entriesReducer中将state设置为空数组吗?(见图)Initial value is 1 instead of []
你知道怎么修吗?谢谢你的帮助:)不要太苛刻了,我是第一次用它;)

商店

// Imports: Dependencies
import AsyncStorage from '@react-native-async-storage/async-storage';
import {applyMiddleware, createStore} from 'redux';
import {createLogger} from 'redux-logger';
import {persistReducer, persistStore} from 'redux-persist';

// Imports: Redux
import rootReducer from '../Reducers/index';

// Middleware: Redux Persist Config
const persistConfig = {
    // Root?
    key: 'root',
    // Storage Method (React Native)
    storage: AsyncStorage,
    // Whitelist (Save Specific Reducers)
    whitelist: [
        'entriesReducer',
    ],
    // Blacklist (Don't Save Specific Reducers)
    blacklist: [],
};

// Middleware: Redux Persist Persisted Reducer
const persistedReducer = persistReducer(persistConfig, rootReducer);

// Redux: Store
const store = createStore(
    persistedReducer,
    applyMiddleware(
        createLogger(),
    ),
);

// Middleware: Redux Persist Persister
let persistor = persistStore(store);

// Exports
export {
    store,
    persistor,
};

索引

// Imports: Dependencies
import { combineReducers } from 'redux';

// Imports: Reducers
import entriesReducer from './entriesReducer';

// Redux: Root Reducer
const rootReducer = combineReducers({
   entriesReducer: entriesReducer,
});

// Exports
export default rootReducer;
d5vmydt9

d5vmydt91#

我遇到了同样的问题,发现了这个有用的线程(https://github.com/rt2zz/redux-persist/issues/1067)。
我有以下配置和减速机。

import { createStore } from "redux";
import reducer from './reducers';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage' ;

const persistConfig = {
    key: 'root',
    storage: AsyncStorage,
};

const persistedReducer = persistReducer(persistConfig, reducer);

export const store = createStore(persistedReducer);
export const persistor = persistStore(store);
const INITIAL_TOKEN_STATE = "";

...

const INITIAL_RECORD_STATE: Array<Record> = [];

const recordReducer = (state = INITIAL_RECORD_STATE, action: { type: string; payload: Record | Array<Record>; }) => {

...

case 'ADD_RECORD':
    state.push(action.payload[0]);
    return state;

}

export default combineReducers({
    ...
    records: recordReducer,
});

我能够持久化除所示数组之外的所有其他(字符串)状态。
我发现问题出在我的reducer中,我正在将(就像您在 entriesReducer 中所做的那样)推到我的状态中的一个数组中,就像这样。

case 'ADD_RECORD':
    state.push(action.payload[0]);
    return state;

我必须替换状态(而不是改变它),以便redux persist触发:

case 'ADD_RECORD':
    state = state.concat(action.payload);
    return state;

在一个自定义转换的帮助下,我能够看到Redux Persists完成它的工作。

import { createTransform } from 'redux-persist';
import { Record } from "../utils/types";

const ArrayTransform = createTransform(
    // transform state on its way to being serialized and persisted.
    (inboundState: Array<Record>, key) => {
        alert("inbound " + JSON.stringify(inboundState));
        return JSON.stringify(inboundState);
    },
    // transform state being rehydrated
    (outboundState: string, key) => {
        alert("outbound " + JSON.stringify(outboundState));
        return JSON.parse(outboundState);
    },
    { whitelist: ['records'] }
);

const persistConfig = {
    key: 'root',
    storage: AsyncStorage,
    transforms: [ArrayTransform]
};

希望这能帮上忙。

相关问题