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

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


内部组件是一个基于类的组件,具有自己的 fetch() 调用,可以为用户呈现数据和图片。外部 HOC 是一个功能组件。要让应用程序正常工作,我所需要做的就是找到一种方法来刷新内部组件并在用户按下按钮时触发 API 调用。我正在尝试使用useStateHOC 中的钩子来执行此操作。


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>

    );

  };

}

一切都工作正常,直到我使用 useState 钩子,它阻止应用程序渲染并显示一条非常讨厌的错误消息。这个:


  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

我的问题是 - (1) 如何useState在 HOC 中使用来在单击按钮时更改状态,以及 (2) 有没有一种更简单的方法可以在按下按钮时重新加载子组件 - 也许不使用状态?


蝴蝶刀刀
浏览 269回答 2
2回答

qq_花开花谢_0

根据文档https://reactjs.org/docs/hooks-rules.html从 React 函数组件调用 Hooks在你的情况下,你的函数不是一个组件,它是一个返回组件的函数您可以更改代码以摆脱 HOC 并使用带有childrenprop的简单组合import React, { useState } from 'react';export default function TinderCard({children}) {&nbsp; &nbsp; const [isLoading, setIsLoading] = useState(false);&nbsp; &nbsp; const refresh = () => {&nbsp; &nbsp; &nbsp; // change state. set isLoading to true and then back to false.&nbsp; &nbsp; &nbsp; setIsLoading(true);&nbsp; &nbsp; &nbsp; setIsLoading(false);&nbsp; &nbsp; };&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; <div className='card&nbsp; user-card-container'>&nbsp; &nbsp; &nbsp; &nbsp; <div className='card-body user-card-inner'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {isLoading ? <h3>Loading...</h3> : children}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div className='buttons-container'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button className='dislike' onClick={() => refresh()}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <i className='fa fa-times'></i>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button className='like' onClick={() => refresh()}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <i className='fa fa-heart'></i>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; );&nbsp;&nbsp;}然后像这样使用它:<TinderCard>&nbsp; <SomeFriend/></TinderCard>

鸿蒙传说

https://codesandbox.io/s/react-hooks-usestate-forked-6pqw7看起来上面的答案提供了问题的部分解决方案,但我只是想指出您的解决方案中可能存在的另一个问题。您的刷新函数调用 setIsLoading 两次。这将导致组件重新渲染,但只会发生一次,并且只会在刷新函数完成执行后发生。您的组件永远不会在状态变量实际为 true 的情况下呈现。此外,与状态变量的 useEffect 挂钩相关的任何效果也不会在刷新时执行。有关如何发生这种情况的示例,请参阅上面的代码沙箱。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript