只设置一次状态

Jka*_*ram 2 state jsx reactjs use-effect

我正在使用一个函数 (getActorInfo()) 来响应从 api 获取信息并将其设置为状态。它可以工作,但该功能不会停止运行。

export default function ActorProfile({ name, img, list, id, getActorInfo }) {
  const [showList, setShowList] = useState(false);
  const [actorInfo, setActorInfo] = useState({});

  getActorInfo(id).then(val => setActorInfo(val));

  console.log(actorInfo)

  return (
    <Wrapper>
      <Actor
        id={id}
        name={name}
        img={img}
        onClick={() => {
          setShowList(!showList);
        }}
        actorBirthday={actorInfo.actorBirthday}
      />
      {showList && <MovieList list={list} actorInfo={actorInfo} />}
    </Wrapper>
  );
}
Run Code Online (Sandbox Code Playgroud)

我试过像这样使用 useEffect

  useEffect(() => {
    getActorInfo(id).then(val => setActorInfo(val));
  }, {});
Run Code Online (Sandbox Code Playgroud)

但我收到一个我不明白的错误

无法对卸载的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。在 ActorProfile 中(在 App.js:60)

我的问题是如何让这个函数只运行一次?

Bri*_*son 6

功能组件主体中的任何内容都将运行每个渲染。改成auseEffect是解决这个问题的正确方法。

它对您不起作用,因为useEffect数组作为第二个参数,而不是object。将其更改为[],它只会运行一次。

useEffect(() => {
  getActorInfo(id).then(val => setActorInfo(val));
}, []);
Run Code Online (Sandbox Code Playgroud)

这将等同于基于类的componentDidMount.

如果您的钩子有依赖项,则将其添加到数组中。然后 effect 会检查你的依赖数组中是否有任何东西发生了变化,如果有的话,只运行钩子。

useEffect(() => {
  // You may want to check that id is truthy first
  if (id) {
    getActorInfo(id).then(val => setActorInfo(val));
  }
}, [id]);
Run Code Online (Sandbox Code Playgroud)

生成的效果将在任何id更改时运行,并且仅getActorInfoidtrue 时调用。这相当于基于类的componentDidMount componentDidUpdate

您可以在useEffect此处阅读有关挂钩的更多信息。

  • `id` 是一个 prop,因此 `id` 应该在数组中(例如,当 `id` 更改时,更改 `actorInfo`)。 (3认同)