React Hooks-使用useState与只是变量

Mos*_*gar 4 javascript node.js reactjs react-hooks

React Hooks给了我们useState选项,我总是看到Hooks与Class-State的比较。但是Hooks和一些常规变量呢?

例如,

function Foo() {
    let a = 0;
    a = 1;
    return <div>{a}</div>;
}
Run Code Online (Sandbox Code Playgroud)

我没有使用Hooks,它将为我带来以下结果:

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}
Run Code Online (Sandbox Code Playgroud)

那么区别是什么?在这种情况下,使用Hooks更加复杂...那为什么要开始使用它呢?

Dre*_*ese 10

局部变量将在每次渲染时重置,而状态将更新:

function App() {
  let a = 0; // reset to 0 on render/re-render
  const [b, setB] = useState(0);

  return (
    <div className="App">
      <div>
        {a}
        <button onClick={() => a++}>local variable a++</button>
      </div>
      <div>
        {b}
        <button onClick={() => setB(prevB => prevB + 1)}>
          state variable b++
        </button>
      </div>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 serene-galileo-ml3f0

  • @NguyễnVănPhong 如果您指的是类属性,则不,它们位于组件生命周期之外。如果您引用在“render”生命周期方法(*例如*)中声明的任何变量,这些变量将在每次渲染时重新声明,就像在功能组件中一样。 (2认同)

mar*_*lin 7

原因是如果您重新useState渲染视图。变量本身仅会更改内存中的位,并且应用程序的状态可能与视图不同步。

比较以下示例:

function Foo() {
    const [a, setA] = useState(0);
    return <div onClick={() => setA(a + 1)}>{a}</div>;
}

function Foo() {
    let a = 0;
    return <div onClick={() => a + 1}>{a}</div>;
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下a,都只有在您useState正确使用视图时,单击的更改才会显示a的当前值。

  • @MosheNagar如果您从道具中获取数据,建议使用局部变量而不是将数据保持在状态中,因为组件无论如何都会在道具更改时重新渲染,因此视图将与数据同步。将它们放入状态只会导致不必要的重新渲染 - 首先是 prop 更改,然后是状态更改。 (7认同)
  • @Tom一般规则是使用本地变量作为派生状态。对于其他任何内容,请使用“useRef”(如果您不想重新渲染)或“useState”(如果您想要重新渲染)。对于计时器,由于它们是副作用,因此应在“useEffect”钩子中启动它们。如果您只想将 `timerId` 用于清理目的,则可以将其保留在 *handler* 的局部变量中。如果您希望能够从组件中的其他位置清除计时器,您应该使用`useRef`。将“timerId”存储在*组件*的局部变量中将是一个错误,因为局部变量在每次渲染时都会“重置”。 (4认同)
  • 查看这个答案的另一种方式是认为在第二种情况下,变量“a”在完成执行后将被垃圾收集,而在第一种情况下,由于它利用“useState”,它将保留“a”的值一个` (3认同)
  • 谢谢!因此,如果我不需要渲染视图 - 只是将我的数据(道具)组织到某个数组中的一种方法 - 我可以使用“let”吗?它对我有用,我只是想知道它是否可以接受。 (2认同)
  • 如果他不想重新渲染视图,他仍然可以使用“useRef”。问题仍然是他应该使用局部变量还是 React 引用。例如,如果您需要清除超时,或者使用 axios 进行持续的 http 请求,您是否将超时或 axios 源存储在变量或 React 引用中? (2认同)