我刚刚启动了一个新的create-react-app项目,并注意到react两次渲染组件!我在 package.json 中的反应版本是"react": "^16.13.1"
import React, { useRef } from "react";
const App = () => {
const renders = useRef(0);
console.log("renders: ", renders.current++);
return (
<div>
Hello
</div>
);
};
这在第一次渲染时产生:
renders: 0
renders: 0
现在,如果我添加一个按钮来增加状态,则每次状态更改都会产生两个附加的渲染:
import React, { useRef } from "react";
const App = () => {
const [count, setCount] = useState(0);
const renders = useRef(0);
console.log("renders: ", renders.current++);
return (
<div>
<button onClick={() => setCount(count + 1)}>increment</button>
<div>count: {count}</div>
</div>
);
};
这将导致:
//--- initial render
renders: 0
renders: 0
//--- first click
renders: 1
renders: 2
//--- second click
renders: 3
renders: 4
//--- third click
renders: 5
renders: 6
这是正常现象还是最新版本的React中的错误?
答案 0 :(得分:3)
好的,看来我找到了原因。检查index.js
后,我发现了以下内容:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
现在看起来像create-react-app的React.StrictMode
可以在开发模式(而不是生产环境)中两次调用某些方法。
答案 1 :(得分:1)
除了您发现的StrictMode问题外,我认为当您使用ref
之类的东西时还会产生副作用,因此通常需要将其放在useEffect
中以防止从渲染两次开始:
import React, { useState, useEffect, useRef } from "react";
const App = () => {
const [count, setCount] = useState(0);
const renders = useRef(0);
useEffect(() => {
// Every time the component has been re-rendered,
// the counter is incremented
console.log("renders: ", renders.current++);
});
return (
<div>
<button onClick={() => setCount(count + 1)}>increment</button>
<div>count: {count}</div>
</div>
);
};
export default App;