Home > Net >  useDispatch doesn't dispatch to the reducer
useDispatch doesn't dispatch to the reducer

Time:01-31

I'm trying to convert an existing project to configureStore from createStore.

store.js :

export default configureStore({
  reducer: {
    articlesList: loadArticlesReducer
  }
});

home.js :

const articlesList = useSelector((state) => state.articlesList);
const dispatch = useDispatch()

useEffect(() => {
  dispatch(getArticles());
})

articleSlice.js :

const articleSlice = createSlice({
  name: 'articles',
  initialState : [],
  reducers : {
    loadArticlesReducer: (state, action) => {
      console.log("WE NEVER REACH THIS CODE") <=== the problem is here
      state = action.payload;
    }
  }
});

export const { loadArticlesReducer } = articleSlice.actions;

export const getArticles = () => dispatch => {
  fetch("https://....")
    .then(response => response.json())
    .then(data => {
      dispatch(loadArticlesReducer(data))
    })
};

The problem, as stated in the comment, is that getArticles action never dispatches the data to loadArticlesReducer.

What am I missing here?

CodePudding user response:

loadArticlesReducer is an action creator, not a reducer function. I suggest renaming the action creator so its purpose isn't confusing to future readers (including yourself) and actually exporting the reducer function.

Example:

const articleSlice = createSlice({
  name: 'articles',
  initialState : [],
  reducers : {
    loadArticlesSuccess: (state, action) => {
      state = action.payload;
    }
  }
});

export const { loadArticlesSuccess } = articleSlice.actions;

export const getArticles = () => dispatch => {
  fetch("https://....")
    .then(response => response.json())
    .then(data => {
      dispatch(loadArticlesSuccess(data));
    });
};

export default articleSlice.reducer; // <-- export reducer function
import articlesReducer from '../path/to/articles.slice';

export default configureStore({
  reducer: {
    articlesList: articlesReducer
  }
});

CodePudding user response:

As per the documentation, you'll need to replace the following line:

export default configureStore({
  reducer: {
    articlesList: loadArticlesReducer // <= This currently points to the exported actions and not the reducer
  }
});

With this one:

import articleReducer from './articleSlice.js'

export default configureStore({
  reducer: {
    articlesList: articleReducer
  }
});

You'll need to export the reducer from the articleSlice.js of course:

export default articleSlice.reducer;

As a general tip, always reproduce the examples from the documentation using exactly the same setup and naming, and once it works, customize the code accordingly in a slow step by step manner. It's easy to miss something while replicating such complicated setups if there's no 1-to-1 correspendence with the original code.

  • Related