Javascript 从React中的高阶组件中重新加载子组件

Javascript 从React中的高阶组件中重新加载子组件,javascript,reactjs,Javascript,Reactjs,我是一个小项目的最后一步,该项目使用高阶组件(HOC)来呈现一个简单的类似Tinder的应用程序 内部组件是一个基于类的组件,具有自己的fetch()调用,用于为用户和图片呈现数据。外部HOC是一个功能组件。我需要做的就是找到一种方法来刷新内部组件,并在用户按下按钮时触发API调用。我正试图用HOC中的useState钩子来实现这一点 import React, { useState } from 'react'; export default function TinderCard(comp

我是一个小项目的最后一步,该项目使用高阶组件(HOC)来呈现一个简单的类似Tinder的应用程序

内部组件是一个基于类的组件,具有自己的fetch()调用,用于为用户和图片呈现数据。外部HOC是一个功能组件。我需要做的就是找到一种方法来刷新内部组件,并在用户按下按钮时触发API调用。我正试图用HOC中的
useState
钩子来实现这一点

import React, { useState } from 'react';

export default function TinderCard(component) {
  return function (props) {
    const [isLoading, setIsLoading] = useState(false);
    const refresh = () => {
      // change state. set isLoading to true and then back to false.
      setIsLoading(true);
      setIsLoading(false);
    };
    const C = component;
    return (
      <div className='card  user-card-container'>
        <div className='card-body user-card-inner'>
          {isLoading ? <h3>Loading...</h3> : <C />}
          <div className='buttons-container'>
            <button className='dislike' onClick={() => refresh()}>
              <i className='fa fa-times'></i>
            </button>
            <button className='like' onClick={() => refresh()}>
              <i className='fa fa-heart'></i>
            </button>
          </div>
        </div>
      </div>
    );
  };
}
我的问题是-(1)当点击按钮时,如何在HOC中使用
useState
来更改状态,以及(2)是否有更简单的方法在按下按钮时重新加载子组件-可能不使用状态?

根据doc

  • 来自React函数组件的调用挂钩
在您的情况下,函数不是组件,而是返回组件的函数

您可以更改代码以摆脱HOC,并使用带有
children
prop的简单组合

import React,{useState}来自“React”;
导出默认函数TinderCard({children}){
const[isLoading,setIsLoading]=useState(false);
常数刷新=()=>{
//更改状态。将isLoading设置为true,然后再设置为false。
设置加载(真);
设置加载(假);
};
返回(
{正在加载?正在加载…:子对象}
刷新()}>
刷新()}>
);
}
然后像这样使用它:


根据文件

  • 来自React函数组件的调用挂钩
在您的情况下,函数不是组件,而是返回组件的函数

您可以更改代码以摆脱HOC,并使用带有
children
prop的简单组合

import React,{useState}来自“React”;
导出默认函数TinderCard({children}){
const[isLoading,setIsLoading]=useState(false);
常数刷新=()=>{
//更改状态。将isLoading设置为true,然后再设置为false。
设置加载(真);
设置加载(假);
};
返回(
{正在加载?正在加载…:子对象}
刷新()}>
刷新()}>
);
}
然后像这样使用它:


上面的答案似乎提供了问题的部分解决方案,但我只想指出解决方案中可能存在的另一个问题。刷新函数调用setIsLoading两次。这将导致重新呈现组件,但只会发生一次,并且只会在刷新函数完成执行后发生。当状态变量实际为true时,将永远不会呈现组件。此外,与状态变量的useEffect挂钩关联的任何效果也不会在刷新时执行。请参阅上面的代码沙盒,以了解如何实现此功能。


上面的答案似乎提供了问题的部分解决方案,但我只想指出解决方案中可能存在的另一个问题。刷新函数调用setIsLoading两次。这将导致重新呈现组件,但只会发生一次,并且只会在刷新函数完成执行后发生。当状态变量实际为true时,将永远不会呈现组件。此外,与状态变量的useEffect挂钩关联的任何效果也不会在刷新时执行。请参阅上面的代码沙盒,了解如何实现此功能。

谢谢@codeofwarrior。实际上,我两次调用setIsLoading是一种惰性方法,用于强制HOC包装的子组件重新渲染。当设置为true时,DOM将呈现JSX元素
加载…
,然后立即再次设置为false,强制元素重新呈现。我只是想不出一个更短的方法来实现这一点,尽管最终它根本不起作用。谢谢@codeofwarrior。实际上,我两次调用setIsLoading是一种惰性方法,用于强制HOC包装的子组件重新渲染。当设置为true时,DOM将呈现JSX元素
加载…
,然后立即再次设置为false,强制元素重新呈现。我只是想不出一个更短的方法来实现这一点,尽管最终它根本不起作用。非常感谢@user1432711。你的回答是最有意义的,当然,这是完成同样事情的一种更漂亮的方式。不过,我使用HOC只是为了练习,所以我想找到一个成功使用它的解决方案。非常感谢@user1432711。你的回答是最有意义的,当然,这是完成同样事情的一种更漂亮的方式。然而,我使用HOC只是为了练习,所以我想找到一个成功使用它的解决方案。
  Line 5:39:  React Hook "useState" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks