当我使用useState
时,它将在控制台2中显示。如果我调用setVal
,它将引发错误Too many re-renders. React limits the number of renders to prevent an infinite loop.
。为什么?
import React from "react";
export default function Home() {
console.log("render");
const [val, setVal] = React.useState();
// setVal(1);
return <div></div>;
}
我认为应该只有1个渲染,如果我叫setVal()
,则只有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>