React Native Redux Сохраняет не сохраняющееся состояние при сочетании с Redux Thunk

Я создаю приложение React Native и использую Redux. Redux Persist работает нормально, но когда я добавляю Redux Thunk, состояние хранилища не сохраняется. Значение переменной state.test меняется на значение, полученное из api, но когда я перезапускаю приложение, значение снова становится равным начальному значению. Я создал простой пример, чтобы воспроизвести это поведение. Пример состоит из 5 файлов, и я также создал репозиторий git с примером кода https://github.com/JenteBeerten/reduxPersistProblem

Магазин / Действия / test.js

export const SET_TEST = 'SET_TEST';

export const fetchTest = () => {
    return async dispatch => {
        fetch('http://dummy.restapiexample.com/api/v1/employee/1',{
            method: 'GET',
            headers: {
            'Content-Type': 'application/json',
            },
            }).then((response) => response.json())
            .then((json) => {
                dispatch({
                    type: SET_TEST, test: json.data.employee_name
                });
            })
            .catch((error) => {
                console.error(error);
            });
    }
};

export const setTest = (test) => {
    return { type: SET_TEST, test: test };
};

Магазин / редукторы / test.js

import { SET_TEST } from "../actions/test";

const initialState = {
    test: 'testInitialValue'
}

const testReducer = (state = initialState, action) => {
    switch (action.type) {
        case SET_TEST:
            state.test = action.test;
            return state;
        default: 
            return state;
    }
}

export default testReducer;

Store / configureStore.js

import { createStore, combineReducers, applyMiddleware } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import AsyncStorage from '@react-native-community/async-storage';
import ReduxThunk from 'redux-thunk';
import testReducer from './reducers/test';

const rootReducer = combineReducers({
  test: testReducer
});

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

const persistedReducer = persistReducer(persistConfig, rootReducer)

export default () => {
  let store = createStore(
    persistedReducer,
    applyMiddleware(ReduxThunk)
  );
  let persistor = persistStore(store)

  return { store, persistor }
}

App.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';

import returnStoreAndPersistor from './store/configureStore';
import TestComponent from './TestComponent';
const {store, persistor} = returnStoreAndPersistor();

export default function App() {


  return (
  <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <View style={styles.container}>
          <TestComponent></TestComponent>
        </View>
      </PersistGate>
  </Provider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

TestComponent.js

import React, { useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';

import { useSelector, useDispatch } from 'react-redux';
import * as testActions from './store/actions/test';

const TestComponent = props => {
  const dispatch = useDispatch();

  var test = useSelector(state => state.test.test);
  console.log('test='+test);

  useEffect(() => {

      dispatch(testActions.fetchTest());
    }, [dispatch]);

    return (
    <View style={styles.container}>
      <Text> Test is {test} </Text>
    </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      }
  });


export default TestComponent;

person Developer12    schedule 16.05.2020    source источник


Ответы (1)


В редукторе вы должны вернуть копию предыдущего состояния как

import { SET_TEST } from "../actions/test";

const initialState = {
    test: 'testInitialValue'
}

const testReducer = (state = initialState, action) => {
    switch (action.type) {
        case SET_TEST:
            return {
             ...state,
            test: action.test;
            }
        default: 
            return state;
    }
}

export default testReducer;

Теперь это будет продолжаться.

Благодарность

person Muhammad Ashfaq    schedule 19.05.2020
comment
Это реализация редуктора по умолчанию. этот фрагмент не имеет отношения к постоянным данным - person Ankush Rishi; 18.05.2021