Search code examples
javascriptreduxredux-thunk

How to overwrite the initial State in Redux


I am writing an application using the backend and I need to make when I open the application. A request was made to the server from which come right condition. Which should rewrite the entire application state.

But now, I can only assign it to the facility "loading/data" and the need only to completely overwrite the Root Redux state.

response from server: https://i.sstatic.net/UClx8.jpg

redux state: https://i.sstatic.net/IJclL.jpg

actions/loading.js

export function fetchTodos(path) {
  return function (dispatch) {
    dispatch({
      type: FETCH_TODOS_REQUEST,
    });
    return axios
      .get(`http://localhost:3000${path}`)
      .then((response) => {
        const { data } = response;
        console.log('data', data);
        dispatch({
          type: FETCH_TODOS_SUCCESS,
          data,
        });
      })
      .catch((error) => {
        const { data } = error.response;
        console.log('data', data);
        dispatch({
          type: FETCH_TODOS_FAILURE,
          error: data,
        });
      });
  };

reducers/index.js

const rootReducer = combineReducers({
  loading,
  Header,
  Main,
  routing: routerReducer,
});

export default rootReducer;

reducers/loading.js

export function loading(state = initialState.loading, action) {
  switch (action.type) {
    case FETCH_TODOS_REQUEST:
      return Object.assign({}, state, {
        isFetching: true,
      });
    case FETCH_TODOS_SUCCESS:
      return Object.assign({}, state, {
        isFetching: false,
        data: action.data.data,
      });
    case FETCH_TODOS_FAILURE:
      return Object.assign({}, state, {
        isFetching: false,
        error: action.error,
      });
    default:
      return state;
  }
}

store/index.js

function configureStoreProd(initialState) {
  return createStore(rootReducer, initialState);
}

function configureStoreDev(initialState) {
  const middlewares = [
    thunk,
  ];
  const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
  const store = createStore(rootReducer, initialState, composeEnhancers(
    applyMiddleware(...middlewares),
    ),
  );

Solution

  • You need to hook into the FETCH_TODOS_SUCCESS action in your Header and Main reducers.

    When you combine reducers then each reducer's state data contains only that reducer's segment.

    For example, your loading reducer will have access to the state.loading segment of your store. To update your store's Main segment, you could do something like:

    // reducers/Main.js
    
    export default (state = initialState.Main, action) => {
        switch (action.type) {
            case FETCH_TODOS_SUCCESS:
                const newMainData = action.data.data.main;
    
                return Object.assign({}, state, newMainData);
            default:
                return state;
        }
    }
    

    As a side note, you should only user uppercase variables for instantiated-type variables (e.g. class-like objects).

    Also, don't forget to update your loading reducer to only pull the loading data from your server response.