React Hooks-使用useState与只是变量


12

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

例如,

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

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

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

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


您正在比较2种不同的东西。带有钩子的第二个功能具有更新数据的能力。第一个并没有真正做任何事情。您可能只是用进行了初始化let a = 1; return <div>{a}</div>,您将获得相同的结果。
Yathi

Answers:


13

原因是如果您重新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的当前值。


谢谢!因此,如果我不需要渲染视图(这只是将我的数据(props)组织到某个数组中的一种方法),我可以使用“ let”吗?它对我有用,我只想知道它可以接受。
Moshe Nagar

@MosheNagar如果您是从props派生数据,建议使用局部变量而不是保持数据处于状态,因为该组件无论如何都会在prop更改时重新呈现,因此视图将与数据同步。将它们置于状态只会导致不必要的重新渲染-首先是更改道具,然后是状态更改。
marzelin

看这个答案另一种方式是,认为在第二种情况下,变量a会被垃圾收集它执行完之后,而在第一个,因为它利用useState它将保留的价值a
若奥·马科斯·皮诺

useRef如果他不想重新渲染视图,他仍然可以使用。问题是他是否应该使用局部变量或React引用。例如,如果您有超时需要清除,或者使用axios正在进行的http请求,您是否将超时或axios源存储在变量或React引用中?
汤姆(Tom)

3
@Tom一般规则是将局部变量用于派生状态。对于其他任何用途,请使用useRef(如果您不想重新渲染)或useState(如果您想要重新渲染)。对于计时器而言,由于它们是副作用,因此应在useEffect钩子中启动。如果timerId仅出于清理目的,则可以将其保留在处理程序的局部变量中。如果您希望能够从组件中的其他位置清除计时器,则应使用useRef。由于将局部变量在每个渲染器上“重置”,因此将组件的局部变量存储timerId在其中将是一个错误。
marzelin

1

更新状态将使该组件再次重​​新渲染,但本地值不会。

就您而言,您已在组件中呈现了该值。这意味着,当更改值时,应重新渲染组件以显示更新后的值。

因此,使用它会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>;
}

0

您的第一个示例仅能工作,因为数据本质上永远不会改变。使用的输入点setState是在状态挂起时重新渲染整个组件。因此,如果您的示例需要某种状态更改或管理,您将很快意识到更改值是必需的,并且要使用变量值更新视图,则需要状态并重新呈现。


0
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. 新状态变量
  2. 该变量的二传手

如果您致电,setA(1)您将致电this.setState({ a: 1 })并触发重新渲染。


0

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.