【问题标题】:What's the best practice to update Redux state in components that needs the same values?在需要相同值的组件中更新 Redux 状态的最佳实践是什么?
【发布时间】:2020-05-28 21:44:08
【问题描述】:

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

我使用 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 中获取数据。

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

提前致谢!

【问题讨论】:

  • /dashboard/orders/:id 处呈现的顶级组件是什么?这就是您应该对该路由进行初始提取调用的地方。
  • 其中一种方法,您可以维护一个State 变量,该变量存储ApiCallsInProgress。当您进行第一次 API 调用时,increment 这个状态变量由1 提供。当收到response 时,decrement1 或简单地在这种情况下将其设置为0。对于调度操作(任何组件)的任何后续 API 调用,请检查此 ApiCallsInProgress 是否为 > 1。如果是,请跳过此 api 调用。希望这会有所帮助
  • @lawrence-witt 这只是一个包含组件的页面。此页面没有状态或任何逻辑。
  • @RohitKhanna 谢谢,我会考虑这个实现。但这是正确的方式吗?

标签: javascript reactjs redux react-redux redux-thunk


【解决方案1】:

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

1:Custom Hooks

  • 您可以有一个钩子来处理 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 传递给需要它的每个嵌套组件)
    • 使用context
const ctx = createContext({...})

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

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

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

【讨论】:

  • 选项 1 非常聪明。我正在一个一个地实现 useEffect,并且在动作中有一个 instances 计数,它将验证它是否大于 0。如果是,我将返回该动作而不调度它,否则我将继续调度该动作.它工作正常。选项 2 也不错,但我不想在父组件中使用它的逻辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2022-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多