【问题标题】:React Higher Order Component With Redux causes infinite loop使用 Redux 反应高阶组件导致无限循环
【发布时间】:2023-03-31 06:42:01
【问题描述】:

我试图在从 API 获取数据时显示加载,我想要一个高阶组件来实现这一点。但是我的代码导致了无限循环

 //home.tsx file
export class Home extends Component<Props, any> {
  componentDidMount(): void {
    this.props.getCharacters();
  }

  render() { 
    return (
    <div></div>
   )
  }
}
const mapStateToProps = (state: AppState): StateProps => {
  return {
    loading:state.marvel.loading,
    data: getResultsSelector(state),
  };
};

const mapDispatchToProps: DispatchProps = {
  getCharacters,
};

export default connect(mapStateToProps, mapDispatchToProps)(WithLoading(Home));

 //hoc.tsx file
function WithLoading(Component:any) {
  return function WihLoadingComponent({ loading, ...props }:any) {

    console.log(loading)
    if (!loading) return <Component {...props} />;
    return <p>Hold on, fetching data might take some time.</p>;
  };
}
export default WithLoading;

我该如何解决这个问题?

【问题讨论】:

    标签: reactjs redux higher-order-components


    【解决方案1】:

    我假设 getCharacters() 是从 API 获取数据的函数。

    组件根据loading挂载,但loading是在组件挂载时设置的。

    1. if (!loading) return &lt;Component /&gt;; 挂载组件。
    2. componentDidMount 调用 getCharacters()
    3. getCharacters() 设置loading = true
    4. if (!loading) return &lt;Component /&gt;; 不再返回组件了。
    5. 加载完成后:loading = false
    6. if (!loading) return &lt;Component /&gt;;再次安装组件。
    7. 在 2 处继续。

    装载和安装必须相互独立。

    • A.要么你不应该调用组件内部的加载,
    • B. 否则您不应该有条件地安装组件。

    A:将加载与组件分开

    由于您可能希望创建一个仅在 loaded === true 时显示某些任意组件的通用 HOC,您可能更喜欢 A.,这意味着您必须设计组件,以便它们不会更改 loading 本身。

    可能有办法做到这一点,例如:

    componentDidMount(): void {
        if( !this.props.dataHasAlreadyBeFetched ){
            this.props.getCharacters();
        }
    }
    

    但我认为这将是一种糟糕的风格,在我看来,在你的情况下,将它分开是有意义的,因为显然你的组件第一次安装的唯一原因是调用 getCharacters,它会卸载组件。

    B:不卸载组件

    组件总是挂载的(没有if( !loading)),并且它本身必须被设计为只有在loading === true(否则null)时才呈现任何内容。当然,loading 也必须传递给组件。

    【讨论】:

    • 感谢您的回答,但我不明白这一点。你能给我一个代码示例吗?
    • 只是不要在组件内部调用getCharacters(),而是在WithLoading HOC 之外的某个地方调用它。
    • 那我如何获取数据。抱歉我不能完全理解。如果您在答案中提供代码示例,我将不胜感激
    • 我为 (B) 添加了一个示例。对于 (A) 可能在父组件的 componentDidMount() 内调用 getCharacters()。但我不知道你到底想达到什么目的。您发布的代码不能像我建议的那样更改为工作。也许正是你想要的是不可能的。另外我想这超出了这个问题的范围。您可以就您不了解的内容提出另一个问题。也许也可以看看componentdidmount
    • 我想在数据获取时显示加载屏幕,我想通过加载 hoc 来实现这一点。这正是我想要的。
    猜你喜欢
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 2020-03-25
    • 1970-01-01
    • 2021-09-07
    • 2021-01-28
    • 2020-10-27
    相关资源
    最近更新 更多