首页 > 解决方案 > 在需要相同值的组件中更新 Redux 状态的最佳实践是什么?

问题描述

我有一些组件可以在一个页面中一起呈现或单独呈现,但它们需要相同的状态(订单信息),这是一个包含所有订单信息的对象。每个组件都使用该状态所需的数据。

我使用 redux 来管理状态,所以当我在一个组件中更新状态时,所有其他组件也可以读取此状态更改并进行更新。

问题是这个状态来自 API,它的初始状态是一个未定义的对象:

const initialState = {
    orderInfo: undefined,
};

这是因为它只有在客户浏览订单时才会有自己的状态。因此,每当客户导航到/dashboard/orders/:id/时,组件都需要从 API 获取数据。

我最初的想法是检查状态是否未定义或是否来自不同的订单 ID。如果是这样,则分派操作以从 API 中获取:

useEffect(() => {
    // check if orderState contains order info and it's the same order
    if (!orderState.orderInfo || orderState.orderInfo._id !== id) {
        dispatch(getOrderInfo(id));
    }
    //eslint-disable-next-line
}, []);

这可行,但我必须对每个组件执行此检查,因为它们可以单独渲染。问题是当页面中有超过 1 个组件时,它们都会同时派发动作以从 API 中获取数据。

只制作一个组件来调度操作的最佳方法是什么?

提前致谢!

标签: javascriptreactjsreduxreact-reduxredux-thunk

解决方案


我认为有两种方法可能对您有好处:

1:自定义挂钩

  • 你可以有一个钩子来处理 useEffect 和调度逻辑,它还使用存储中数据的选择器。就像是:
function useOrder(foo, bar) {
  const dispatch = useDispatch()
  const order = useSelector(selectOrder)
  useEffect(() => {
    if (foo) {
      dispatch(bar)
    }
  }, [foo, bar])

 return order
}

然后只需通过以下方式在您的组件中使用它:

const order = useOrder(foo, bar)

2.- 父容器。

  • 如果所有组件同时存在,则可能必须有一个包含所有组件的全局容器。您可以在那里处理您的调度逻辑并传递属性。对于传递道具,您还有 2 个选项:
    • 通过 prop 显式传递(因此只需将 prop 传递给每个需要它的嵌套组件)
    • 使用上下文
const ctx = createContext({...})

<Provider context={ctx}>
 // Your component hierarchy
</Provider>

然后在每个组件内部使用useContext钩子。

*编辑:在第一个钩子示例中,我将道具直接传递给钩子,但对于您的示例,您也可以从另一个选择器中获取该道具。


推荐阅读