简体   繁体   English

反应钩子。 将值作为参数传递给 useReducer()

[英]React Hooks. Pass value as argument to useReducer()

It is my first time using useReducer() hook and I am facing a problem where I need to pass it a value as argument.这是我第一次使用 useReducer() 钩子,我面临一个问题,我需要将一个值作为参数传递给它。

Here is how my reducer looks like:这是我的减速器的样子:

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

As you can see, what I am doing is:如您所见,我正在做的是:

1- If the action type is "save", increase the total saves for the book, add the new book data to a Map of "visitedBooks" which I have in a Context (ignore this part), and update my currentUser data increasing his total saves. 1-如果操作类型为“保存”,则增加书籍的总保存量,将新书籍数据添加到我在上下文中拥有的“已访问书籍”的地图中(忽略此部分),并更新我的 currentUser 数据以增加他的总节省。

2- If the action type is "unsave", I do the opposite. 2- 如果操作类型是“未保存”,则相反。

My problem is that I need to pass an argument "reviews" to the reducer.我的问题是我需要将参数“评论”传递给减速器。 For example, if I have this function for fetching "extra data" from my db:例如,如果我有这个函数来从我的数据库中获取“额外数据”:

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

       return reviews;
   }  

and I use it like this:我像这样使用它:

  const reviews = await fetchReviews(bookId);
  

how can I pass the reviews as argument to the reducer?如何将评论作为参数传递给减速器?

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

Thank you.谢谢你。

You already pass down an object to dispatch() and nothing stops you to add a payload along with the type :您已经将一个对象传递给dispatch()并且没有什么可以阻止您添加payloadtype

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

This way you can access the reviews in your reducer ( action.payload ).通过这种方式,您可以访问减速器中的评论( action.payload )。

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

When you call the dispatch method, you're passing an object which has the type field.当您调用dispatch方法时,您正在传递一个具有type字段的对象。 The format of this object is actually up to you to define.这个对象的格式实际上是由你来定义的。 If you need to pass parameters other than type you can freely do so.如果您需要传递type以外的参数,您可以自由地这样做。

For example例如


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

Then in your reducer you can you the payload object然后在您的减速器中,您可以使用payload对象

// Reducer 

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

I suggest reading this article https://redux.js.org/basics/actions我建议阅读这篇文章https://redux.js.org/basics/actions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 generics 类型传递给 React Hooks useReducer - How to pass generics type to React Hooks useReducer 反应钩子。 定期运行使用效果 - React hooks. Periodic run useEffect 无法使用 react 和 hooks 访问嵌套的 JSON。 类型错误 - Can't access nested JSON with react & hooks. TypeErrors 反应钩子。 父组件不重新渲染以执行条件语句 - React Hooks. Parent component not rerendering to execute conditional statement 通过 React 钩子的组件动画。 Gsap 没有反应 - Animation of a component via React hooks. Gsap doesn't respond 反应 useContext useReducer state 挂钩错误 - React useContext useReducer state Hooks Error 如何使用 react hooks useEffect/useReducer + useContext 优雅地更改 ts 中上下文的值? - How to use react hooks useEffect/useReducer + useContext to change context's value in ts gracefully? 我需要将以下代码编写为 React Hooks。 可以这样写吗? - I need the below code written as React Hooks. Is it possible to write it so? 使用Hooks将React类转换为功能组件。 如何解决“不受控制的输入”错误 - Converting React Class to Functional Components with Hooks. How to fix “uncontrolled input” error React Hooks - useReducer:在触发函数之前等待减速器完成 - React Hooks - useReducer: Wait for reducer to finish before triggering a function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM