redux useDispatch不发送到Reducer

vwkv1x7d  于 2023-02-04  发布在  其他
关注(0)|答案(2)|浏览(126)

我正在尝试将现有项目从createStore转换为configureStore
商店. js:

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

首页. js:

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

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

文章切片. 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))
    })
};

正如注解中所述,问题在于getArticles操作从不将数据分派到loadArticlesReducer
我错过了什么?

xyhw6mcr

xyhw6mcr1#

loadArticlesReducer是一个动作创建器,而不是一个reducer函数,我建议重命名这个动作创建器,这样它的目的就不会让未来的读者(* 包括你自己 *)感到困惑,并且实际上导出这个reducer函数。
示例:

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
  }
});

您还可以考虑使用createAsyncThunkgetArticles转换为更惯用的RTK thunk函数。您可以使用切片的extraReducers来处理从thunk返回的已实现的Promise。示例:

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

export const getArticles = createAsyncThunk(
  "articles/getArticles",
  () => {
    return fetch("https://....")
      .then(response => response.json());
  }
);

const articleSlice = createSlice({
  name: 'articles',
  initialState : [],
  extraReducers: builder => {
    builder.addCase(getArticles.fulfilled, (state, action) => {
      state = action.payload;
    });
  },
});

export default articleSlice.reducer;
xe55xuns

xe55xuns2#

根据documentation,您需要替换以下行:

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

有了这个:

import articleReducer from './articleSlice.js'

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

当然,您需要从articleSlice.js导出减速器:

export default articleSlice.reducer;

作为一个一般性的提示,总是使用完全相同的设置和命名来复制文档中的示例,一旦成功了,就以缓慢的一步一步的方式相应地定制代码。如果与原始代码没有一一对应的关系,那么在复制如此复杂的设置时很容易漏掉一些东西。

相关问题