【问题标题】:Prevent useState value from being reset when props change防止在 props 更改时重置 useState 值
【发布时间】:2021-01-05 13:11:45
【问题描述】:

我有一个看起来像这样的组件:

//@flow
import React, { useState } from "react";

type Props = {
  likes: int,
  toggleLike: () => void,
};

const Foo = (props: Props) => {
  const [open, setOpen] = useState(false);
  const style = `item${open ? " open": ""}`;
  return (
    <div className={style} onMouseOver={() => setOpen(true)} onFocus={() => setOpen(true)} onMouseOut={() => setOpen(false)} onBlur={() => setOpen(false)}>
      <button onClick={props.toggleLike}>Toggle like</button>
    </div>
  );
};

export default Foo;

open 状态用于在鼠标悬停时应用“打开”类。如果我调用toggleLike() prop 函数,就会出现问题,因为这会更新 props,并且组件会重新渲染,open 重置为 false。由于样式使用了过渡,这会导致动画重新运行,因为它变回 false,然后由于鼠标悬停在其上而变为 true。

那么,如何防止open 在每次后续渲染中被重置回false?看起来应该很简单,但是在通过https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state 之后,我似乎无法在我的情况下应用它。

【问题讨论】:

  • React 不是这样工作的,我猜你在toggleLike 上卸载了组件,这会导致状态重置。只是不要这样做。此外,如果您提供代码框会更好:How to create a Minimal, Reproducible Example
  • @DennisVash 不,它不会卸载toggleLike 上的组件。有一个 HOC 可以处理这个问题 - 调用会触发 AJAX 请求并更新它自己的状态,该状态会作为 props 传递给这个组件。
  • 问题显然出在您未显示的部分代码的父级中。再说一次,这个说法是不正确的:“因为这会更新道具,并且组件被重新渲染并打开重置为假”

标签: reactjs react-hooks


【解决方案1】:

状态不会在道具改变时重置。状态是基于每个组件的,并且在整个重新渲染过程中都会保留,因此被称为“状态”。

正如 Dennis Vash 已经提到的,问题很可能是由组件被卸载或替换为相同的组件引起的。您可以通过将其添加到您的组件来轻松验证这一点:

useEffect(() => {
  console.log("Mounted")
}, [])

您应该在控制台中看到多个“已安装”。

如果没有办法阻止组件被替换或卸载,请考虑将状态放入上下文中并在组件中使用该上下文,因为您还可以将每个组件包装到自己的上下文中以赋予其独特性,非全局,状态。

【讨论】:

  • 是的,看起来它正在被相同的组件替换
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多