组件是否渲染了两次?是codesandbox问题吗?
Is component rendered twice? Is it codesandbox problem?
这是我的简单 React 应用程序:
let idCounter = 0;
export default function App() {
const id = useMemo(() => {
console.log("useMemo");
return idCounter++;
}, []);
console.log("render", id);
useEffect(() => {
console.log("useEffect", id);
});
return id;
}
https://codesandbox.io/s/morning-bush-swky8
这是控制台输出:
useMemo
render 0
useEffect 1
为什么在useEffect中id
等于1?
好像组件渲染了两次,但是为什么useMemo和useEffect没有被调用到第二次呢? id 是如何变成 1?
Starting with React 17, React automatically modifies the console
methods like console.log() to silence the logs in the second call to
lifecycle functions. However, it may cause undesired behavior in
certain cases where a workaround can be used.
您的组件确实被渲染了两次,但是在 StrictMode
.
引起的第二次重新渲染期间,React 隐藏了日志语句
如果删除 StrictMode
.
,您将获得预期的输出
另一种选择是在 console
对象上使用不同的方法进行日志记录,例如 console.dir
.
let idCounter = 0;
function App() {
const id = React.useMemo(() => {
console.dir("useMemo");
return idCounter++;
}, []);
console.dir("render");
console.dir(id);
React.useEffect(() => {
console.log("useEffect", id);
});
return id;
}
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
document.querySelector("#root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.min.js"></script>
<div id="root"></div>
这是我的简单 React 应用程序:
let idCounter = 0;
export default function App() {
const id = useMemo(() => {
console.log("useMemo");
return idCounter++;
}, []);
console.log("render", id);
useEffect(() => {
console.log("useEffect", id);
});
return id;
}
https://codesandbox.io/s/morning-bush-swky8
这是控制台输出:
useMemo
render 0
useEffect 1
为什么在useEffect中id
等于1?
好像组件渲染了两次,但是为什么useMemo和useEffect没有被调用到第二次呢? id 是如何变成 1?
Starting with React 17, React automatically modifies the console methods like console.log() to silence the logs in the second call to lifecycle functions. However, it may cause undesired behavior in certain cases where a workaround can be used.
您的组件确实被渲染了两次,但是在 StrictMode
.
如果删除 StrictMode
.
另一种选择是在 console
对象上使用不同的方法进行日志记录,例如 console.dir
.
let idCounter = 0;
function App() {
const id = React.useMemo(() => {
console.dir("useMemo");
return idCounter++;
}, []);
console.dir("render");
console.dir(id);
React.useEffect(() => {
console.log("useEffect", id);
});
return id;
}
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
document.querySelector("#root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.min.js"></script>
<div id="root"></div>