我有一些组件可以在页面中一起呈现,也可以单独呈现,但它们需要相同的状态(订单信息),这是一个包含所有订单信息的对象。每个组件都使用这个状态中的数据。
我使用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
}, []);
这样做是可行的,但我必须在每个组件上实现这个检查,因为它们可以单独渲染。问题是当页面中有多个组件时,所有组件都会在同一时间派发动作从API中获取数据。
有什么办法可以让只有一个组件来调度动作?
先谢谢你
我想有两种方法可能对你有好处。
1: 自定义钩子
function useOrder(foo, bar) {
const dispatch = useDispatch()
const order = useSelector(selectOrder)
useEffect(() => {
if (foo) {
dispatch(bar)
}
}, [foo, bar])
return order
}
然后通过以下方式在你的组件中使用它: 2:
const order = useOrder(foo, bar)
2、父容器。
const ctx = createContext({...})
<Provider context={ctx}>
// Your component hierarchy
</Provider>
然后在每个组件中使用 useContext
钩子。
*编辑:在第一个钩子的例子中,我直接把道具传给了钩子,但是对于你的例子,你也可以从另一个选择器中获取道具。