反应useState重新渲染

时间:2020-09-01 20:17:30

标签: reactjs react-hooks

当我使用useState时,它将在控制台2中显示。如果我调用setVal,它将引发错误Too many re-renders. React limits the number of renders to prevent an infinite loop.。为什么?

https://codesandbox.io/s/focused-black-j1zow?fontsize=14&hidenavigation=1&theme=dark&file=/src/App.js

import React from "react";

export default function Home() {
  console.log("render");
  const [val, setVal] = React.useState();
  // setVal(1);
  return <div></div>;
}

我认为应该只有1个渲染,如果我叫setVal(),则只有2个渲染,对吧?

2 个答案:

答案 0 :(得分:1)

如果您使用 create-react-app 来启动应用程序,则index.js文件中必须包含<React.StrictMode>包装器:

<React.StrictMode>
    <App />
</React.StrictMode>

发生这种情况的原因是React.StrictMode的故意功能。

删除该包装,并且应该对其进行修复。

答案 1 :(得分:0)

这是一个摘要,展示了使用useState设置和处理状态的三种基本方式。

通过向val1提供初始值,将

useState设置为1,并且不变。

val2最初没有设置,但是在初始渲染之后调用useEffect并将其值设置为set with useEffect。我们为useEffect提供了一个空的依赖项数组,因此它将仅运行一次。

val3的初始化方式与val1相同,并且其值通过handleClick函数进行了更改。

对于您有关渲染数量的问题,useState寻找状态变化并相应地调用渲染。通过以自己的方式调用setState,可以更改每个渲染的状态,从而触发新的渲染...无限。应当指出,这不是一对一的过程。 docs非常清楚地引导您完成操作。

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<div id="App"></div>
<script type="text/babel">
  const { useState, useEffect} = React;

function Home() {
  console.log("render");
  const [val1, setVal1] = React.useState(1);
  const [val2, setVal2] = React.useState();
  const [val3, setVal3] = React.useState('Click me');
  
  useEffect(()=>{
    setVal2('set with useEffect');
  },[])
  
  const handleClick = () => {
    setVal3('set with handler');
  }

  return (
    <div>
      <p>{val1}</p>
      <p>{val2}</p>
      <button type="button" onClick={handleClick}>{val3}</button>
    </div>
  );
}

ReactDOM.render(<Home />, document.getElementById('App'));

 </script>