【问题标题】:Loading flags with Redux saga and React functional components使用 Redux saga 和 React 功能组件加载标志
【发布时间】:2023-04-10 20:00:02
【问题描述】:

在 redux 状态和基于类的组件中使用标志时,生活是美好的。您在 componentWillMount 中启动 API 调用,当组件被挂载并且 render() 函数运行时,您在 redux 中正确设置了标志,这意味着不会出现不需要的内容 (FUC)。

这很好,但我们现在使用的是函数式组件。在这种情况下,我们通过 useEffect() 运行 API 调用,这意味着我们只在第二次渲染时在 redux 中设置标志。在简单组件的情况下:

function SimpleComponent() {
   const isLoading = useSelector(selectIsLoading);
   const dispatch = useDispatch();

   useEffect(() => {
     dispatch(startApiRequest());
   },[dispatch]);

   if (isLoading) {
     return <LoadingComponent />;
   }

   return <ContentThatWillBreakIfApiCallIsNotFinished />;
}

这段代码的行为如下:

render 1: isLoading is false, you show broken content.
after render 1: useEffect runs, sets isLoading to true
render 2: isLoading is true, you no longer show broken content

一个简单的解决方案是使用 isLoading 设置为 true 来初始化存储。这意味着您必须确保在退出组件时始终将其返回为 true。如果在多个组件中使用相同的标志,这可能会导致错误。这不是一个理想的解决方案。

使用 redux-thunk,我们可以使用具有内部 isLoading 标志的自定义钩子,而不是在 redux 中设置标志。比如:

const apiCallWithLoadingIndicator = () => {
  const [isLoading, setIsLoading] = useState(true);
  const dispatch = useDispatch();

  useEffect(() => {
    (async () => {
      await dispatch(asyncThunkReturningPromise());
      setIsLoading(false);
    })()
  }, [setIsLoading, dispatch]);
  return isLoading;
}

redux-saga 似乎没有一种简单的方法来实现这一点,其中使用生成器而不是承诺。在 redux-saga 中处理带有功能组件的加载标志的最佳实践是什么?

【问题讨论】:

  • 问题:你有充分的理由在这里使用 saga 吗?一般来说,我们只推荐它用于非常复杂的用例,即使那样你也应该在适用的情况下将它与 thunk 混合使用(参见redux.js.org/style-guide/style-guide/…)。此外,仅供参考,官方 Redux Toolkit 附带完整的 api 缓存解决方案,因此如果您使用它,您将不需要 thunk 或 saga 来获取数据。 redux-toolkit.js.org/rtk-query/overview
  • @phry 对于 99% 的项目,我总是更喜欢 redux-toolkit 和 thunk。我目前正在支持一个使用 redux-saga 的遗留项目,它绝不需要使用 redux-saga。重写将是一项痛苦而漫长的工作。

标签: reactjs redux redux-saga


【解决方案1】:

通常:componentWillMount 已被弃用多年,可能会在 React 18 中被删除 - 你也不应该在类组件中使用它。

也就是说,通常它有助于以“未初始化”状态值之类的东西开始初始状态,它告诉您,虽然它没有加载,但它甚至还没有开始做任何事情并处理它与组件中的“加载”相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    • 2020-11-19
    • 2021-06-09
    • 2020-08-07
    • 1970-01-01
    相关资源
    最近更新 更多