简体   繁体   English

React Hooks - 使用 useState 与仅使用变量

[英]React Hooks - using useState vs just variables

React Hooks give us useState option, and I always see Hooks vs Class-State comparisons. React Hooks 为我们提供了 useState 选项,我总是看到 Hooks 与 Class-State 的比较。 But what about Hooks and some regular variables?但是 Hooks 和一些常规变量呢?

For example,例如,

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

I didn't use Hooks, and it will give me the same results as:我没有使用 Hooks,它会给我相同的结果:

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

So what is the diffrence?那么有什么区别呢? Using Hooks even more complex for that case...So why start using it?在这种情况下使用 Hooks 甚至更复杂......那么为什么要开始使用它呢?

The reason is if you useState it rerenders the view.原因是如果你useState它会重新呈现视图。 Variables by themselves only change bits in memory and the state of your app can get out of sync with the view.变量本身只会更改 memory 中的位,而您的应用程序的 state 可能会与视图不同步。

Compare this examples:比较这个例子:

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

In both cases a changes on click but only when you use useState the view correctly shows a 's current value.在这两种情况下,点击都会a变化,但只有当您使用useState时,视图才能正确显示a的当前值。

Local variables will get reset every render upon mutation whereas state will update:局部变量将在每次渲染时重置,而 state 将更新:

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

编辑 serene-galileo-ml3f0

Updating state will make the component to re-render again, but local values are not.更新 state 将使组件再次重新渲染,但本地值不会。

In your case, you rendered that value in your component.在您的情况下,您在组件中呈现了该值。 That means, when the value is changed, the component should be re-rendered to show the updated value.这意味着,当值更改时,应该重新渲染组件以显示更新后的值。

So it will be better to use useState than normal local value.所以使用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>;
}
function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

is equivalent to相当于

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

What useState returns are two things: useState返回的是两件事:

  1. new state variable新 state 变量
  2. setter for that variable该变量的设置器

if you call setA(1) you would call this.setState({ a: 1 }) and trigger a re-render.如果你调用setA(1)你会调用this.setState({ a: 1 })并触发重新渲染。

Your first example only works because the data essentially never changes.您的第一个示例仅有效,因为数据基本上从未更改。 The enter point of using setState is to rerender your entire component when the state hanges.使用setState的入口点是在 state 挂起时重新渲染整个组件。 So if your example required some sort of state change or management you will quickly realize change values will be necessary and to do update the view with the variable value, you will need the state and rerendering.因此,如果您的示例需要某种 state 更改或管理,您将很快意识到更改值是必要的,并且要使用变量值更新视图,您将需要 state 和重新渲染。

It is perfectly acceptable to use standard variables.使用标准变量是完全可以接受的。 One thing I don't see mentioned in other answers is that if those variables use state-variables, their value will seemingly update on a re-render event.我在其他答案中没有提到的一件事是,如果这些变量使用状态变量,它们的值似乎会在重新渲染事件时更新。

Consider:考虑:

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.
*/

Updating firstName or lastName sets the state and causes a re-render.更新firstNamelastName会设置 state 并导致重新渲染。 As part of that process fullName is assigned the new value of firstName or lastName .作为该过程的一部分, fullName被赋予firstNamelastName的新值。 There is no reason to place fullName in a state variable.没有理由将fullName放在 state 变量中。

In this case it is considered poor design to have a setFullName state-setter because updating the firstName or lastName would cause a re-render and then updating fullName would cause another re-render with no perceived change of value.在这种情况下,使用setFullName状态设置器被认为是糟糕的设计,因为更新firstNamelastName会导致重新渲染,然后更新fullName会导致另一次重新渲染,而没有感知到值的变化。


In other cases, where the view is not dependent on the variable, it is encouraged to use local variables;在其他情况下,视图不依赖于变量,鼓励使用局部变量; for instance when formatting props values or looping;例如在格式化道具值或循环时; regardless if whether the value is displayed.不管是否显示该值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM