React w / Redux / React-Redux и Redux-Persist сохраняют только первое изменение в локальном хранилище - PullRequest
0 голосов
/ 07 апреля 2020

У меня несколько проблем с сохранением Redux в React с использованием React-Redux и Redux-Persist.

Пример редуктора:

export default (state = {}, action) => {
    switch (action.type) {
      case "SET_FOO":
        return action.payload
      default:
        return state;
    }
  };

Пример действия:

const setFooAction = (payload) => {
    return {
      type: "SET_FOO",
      payload
    }
  }
  export default setFooAction;

Индекс. js

import { createStore, combineReducers } from "redux";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import { PersistGate } from 'redux-persist/integration/react'
import fooReducer from "redux/reducers/setFooReducer";

const persistConfig = {
  key: "root",
  storage
};

const rootReducer = combineReducers({
  foo: fooReducer 
});

const persistedReducer = persistReducer(persistConfig, rootReducer);

let state = {
  foo: {}
}

let store = createStore(
    persistedReducer, 
    state, 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
let persistor = persistStore(store);

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById("root")
);

Использование в компоненте:

import { connect } from "react-redux";
import setFoo from "redux/actions/setFooAction";

class Main extends Component {        
    //... More Code
    componentDidMount() {
        let foo = this.getFoo() //Gets foo, doesn't really exist but just for context
        this.props.setFoo(foo); //Works fine, all gets set, data is persisted
    }    
    addNewFoo = () => {    
        //Called after functions runs somewhere    
        let newFoo = this.getNewFoo() //Gets newFoo, doesn't really exist but just for context
        foo.push(newFoo)
        this.props.setFoo(foo); //Sets Redux store, on refresh, doesn't persist    
    }
    //...More Code    
}

const mapStateToProps = (state) => ({
  ...state,
});

const mapDispatchToProps = (dispatch) => ({
   setFoo: (payload) => dispatch(setFoo(payload)) 
});

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

Первоначально , все работает нормально:

  • Приложение загружается
  • Начальное состояние установлено в приложении
  • При этом обновляется хранилище Redux
  • PERSIST, и оно сохраняется в локальном хранилище.
  • При обновлении sh все сохраняется, как и ожидалось после первой загрузки данных.
  • Первое обновление каждого из различных объектов в магазине Redux.

Однако ...

Если я решу добавить что-то новое в мой объекты и установить / обновить их в хранилище Redux ...

... при refre sh, только то, что было изначально сохранено, все еще присутствует во время REHYDRATE (если я правильно понимаю события Redux) .

Теперь я буду Я думаю, что это как-то связано с неизменностью моих объектов, и Redux не получает изменений из-за этого, но я попытался изменить свои редукторы безуспешно:

Попытка редуктора:

export default (state = {}, action) => Object.assign(state, {
   foo: action.payload !== "SET_FOO" ? state.foo : action.payload
});

Я попробовал вышеупомянутое (а также комбинацию этого и моего оригинала, который просто сломал вещи). Это сработало, но я устанавливал мое состояние следующим образом:

state {
    foo: {
        foo: {
           //Foo data
        }
    }
}

Я знаю, что это просто присвоение foo снова из-за добавления foo: в редуктор ...

... однако, я не уверен, как это исправить, не сделав что-то неправильно в Redux!

Итак, моя осторожность возобладала, и я подумал, что лучше спросить, есть ли у кого-нибудь предложения или темы, которые Я могу потянуть на!

Спасибо за любую помощь заранее !!!

1 Ответ

2 голосов
/ 07 апреля 2020

На первый взгляд все выглядит хорошо.

Ваш Object.assign в редукторе может быть причиной того, что вызывает вложенные foo объекты, потому что один из них на принципах Redux - неизменяемость, поэтому вы всегда должны возвращать новое состояние, вместо этого вы непосредственно мутируете state.

. Вы можете добавить еще один первый параметр, чтобы создать новый объект, который будет иметь свойства состояния с новым foo:

export default (state = {}, action) => Object.assign({}, state, {
   foo: action.payload !== "SET_FOO" ? state.foo : action.payload
});

Лучшим подходом, который вы часто будете видеть, будет:

export default (state = {}, { type, payload }) => {
  switch (type) {
    case 'SET_FOO': {
      return { ...state, payload }
    }

    default: {
      return state
    }
  }
}

В этом последнем примере вы можете ясно представить, что я возвращаю новый объект со всеми свойствами, которые в состоянии имеет, плюс новый полезный груз.

Удачи!

...