NodeJS React挂钩-使用useState与仅使用变量

w8ntj3qf  于 2023-01-08  发布在  Node.js
关注(0)|答案(6)|浏览(180)

React Hooks提供了useState选项,我经常看到Hooks与类状态的比较,但是Hooks和一些正则变量呢?
例如,

function Foo() {
    let a = 0;
    a = 1;
    return <div>{a}</div>;
}

我没有使用钩,它会给我相同的结果:

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

那么有什么区别呢?使用钩子对这种情况来说更复杂...那么为什么要开始使用它呢?

vkc1a9a2

vkc1a9a21#

原因是如果你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>;
}

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

mhd8tkvw

mhd8tkvw2#

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

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>
  );
}

7cwmlq89

7cwmlq893#

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

相当于

class Foo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            a: 0
        };
    }
    // ...
}

useState返回两个结果:
1.新状态变量
1.变量设置器
如果调用setA(1),则将调用this.setState({ a: 1 })并触发重新呈现。

vuktfyat

vuktfyat4#

你的第一个例子之所以有效是因为数据基本上不会改变。使用setState的切入点是在状态挂起时重新呈现整个组件。因此,如果你的例子需要某种状态更改或管理,你会很快意识到更改值是必要的,并且要用变量值更新视图,你将需要状态和重新呈现。

siotufzp

siotufzp5#

更新状态将使组件再次重新呈现,但本地值不会。
在您的示例中,您在组件中呈现了该值,这意味着,当该值更改时,组件应该重新呈现以显示更新后的值。
因此,使用useState比使用正常的本地值更好。

function Foo() {
    let a = 0;
    a = 1; // there will be no re-render.
    return <div>{a}</div>;
}

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // re-render required
    return <div>{a}</div>;
}
fumotvh3

fumotvh36#

使用标准变量是完全可以接受的,有一点我没有看到其他答案提到,如果这些变量使用状态变量,它们的值似乎会在重新呈现事件时更新。
考虑:

import {useState} from 'react';

function NameForm() {
  // State-managed Variables
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  // State-derived Variables
  const fullName = `${firstName} ${lastName}`;

  return (
    <input value={firstName} onChange={e => setFirstName(e.target.value)} />
    <input value={lastName} onChange={e => setLastName(e.target.value)} />
    {fullName}
  );
}

/*
Description: 
  This component displays three items:
    - (2) inputs for _firstName_ and _lastName_ 
    - (1) string of their concatenated values (i.e. _lastName_)
  If either input is changed, the string is also changed.
*/

更新firstNamelastName将设置状态并导致重新呈现。作为该过程的一部分,将为fullName分配新值 * firstName * 或 * lastName *。没有理由将 * fullName * 放在状态变量中。
在这种情况下,具有setFullName状态设置器被认为是糟糕的设计,因为更新 * firstName * 或 * lastName * 将导致重新呈现,然后更新 * fullName * 将导致另一次重新呈现,而没有感知到值的更改。
在其他情况下,视图不依赖于变量,则鼓励使用局部变量;例如当格式化 prop 值或循环时;而不管是否显示该值。

相关问题