React Hooks. 将值作为参数传递给 useReducer()

7

这是我第一次使用useReducer()钩子,并且我遇到了一个问题,需要将一个值作为参数传递给它。

以下是我的reducer代码:

  const memoizedReducer = useCallback((state, action) => {
    switch (action.type) {
      case "save":
        const refreshedBookData = {
          ...state.bookData,
          ...(state.bookData.totalSaves >= 0 && {
            totalSaves: state.bookData.totalSaves + 1,
          }),
          isSaved: true,
        };
       
        // Add the new book data to a Map which I have in a Context provider
        currentUser.addBookToVisitedBooks(bookId, refreshedBookData);
        
        // Update my context provider data
        currentUser.setData((prevCurrentUserData) => {
          return {
            ...prevCurrentUserData,
            ...(prevCurrentUserData.totalSaves >= 0 && {
              totalSaves: prevCurrentUserData.totalSaves + 1,
            }),
          };
        });
        
        return refreshedBookData;

    case "unsave":
        const refreshedBookData = {
          ...state.bookData,
          ...(state.otheBookData.totalSaves >= 0 && {
            totalSaves: state.bookData.totalSaves - 1,
          }),
          isSaved: false,
        };

        // Add the new book data to a Map which I have in a Context provider
        currentUser.addBookToVisitedBooks(bookId, refreshedBookData);
      
        // Update my context provider data
        currentUser.setData((prevCurrentUserData) => {
          return {
            ...prevCurrentUserData,
            ...(prevCurrentUserData.totalSaves > 0 && {
              totalSaves: prevCurrentUserData.totalSaves - 1,
            }),
          };
        });
        
        return refreshedBookData;
      
    default:
        return state;
});


const [{ bookData }, dispatch] = useReducer(memoizedReducer, {
   bookData: params?.bookData
});

正如您所看到的,我正在做的事情是:

1- 如果操作类型是“save”,则增加该书籍的总保存次数,将新书籍数据添加到我在上下文中拥有的“visitedBooks”映射中(忽略此部分),并更新我的currentUser数据以增加他的总保存次数。

2- 如果操作类型是“unsave”,则执行相反的操作。

我的问题是,我需要向reducer传递一个参数“reviews”。例如,如果我有一个从数据库中获取“额外数据”的函数:

   const fetchReviews = async (bookId) => {
       // Get a list of reviews from the db
       const reviews = await db.fetchReviews(bookId);

       return reviews;
   }  

我是这样使用它的:

  const reviews = await fetchReviews(bookId);
  

如何将评论作为参数传递给Reducer?
  dispatch({ type: saved ? "save" : "unsave" }); 

感谢您的选择。
2个回答

11

您已经向dispatch()传递了一个对象,没有任何阻止您在type后面添加payload:

dispatch({ 
  type: saved ? "save" : "unsave",
  payload: reviews,
});

通过这种方式,您可以在 reducer (action.payload) 中访问评论。

const reducer = (state, action) => {
  // action has `type` and `payload` properties
}

1
非常感谢!还有一个问题,更多关于你的个人意见,是否建议将类似 useReducer 动作的代码进行泛化处理? - Raul

3
当您调用dispatch方法时,您正在传递一个具有type字段的对象。实际上,该对象的格式由您自己定义。如果您需要传递除type之外的参数,可以随意这样做。
例如:

const reviews = {....} ; /// reviews  
dispatch({ type: 'save', payload: reviews });

然后在你的reducer中,你可以使用payload对象。

// Reducer 

const reducer = (state, action) => {
    switch (action.type) {
        case 'save':
            const reviews = action.payload;
            //.....
            break;
    }
}

我建议阅读这篇文章 https://redux.js.org/basics/actions


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接