提问人:Andrew Chung 提问时间:11/17/2023 最后编辑:Henry WoodyAndrew Chung 更新时间:11/19/2023 访问量:44
useEffect 在一个非常简单的 NextJS 应用程序(v13.4+,应用程序路由器)中运行 3 次。为什么会这样?
useEffect running 3 times in a very simple NextJS app (v13.4+, app router). Why is this the case?
问:
我在 v13.4+ 中有一个非常简单的 NextJS 应用程序,它运行 useEffect 3 次(即使它设置了一个空的依赖数组。
我希望由于空数组,它只会运行 1 次(相当于 componentDidMount)。
我不确定为什么useEffect运行了三次。我在useEffect中放置了一个getData调用,我希望当用户转到页面时不要运行三次。
// /app/page.js
import react, { useEffect, useState } from 'react'
export default Page() {
const [myData, setMyData] = useState([]);
// this is calling a router handler
const getData = async () => {
const response = await fetch('/api/data', {
method: 'GET',
});
if (response.ok) {
console.log('Response.Ok');
const { data } = await response.json();
setMyData((prev) => data);
} else {
console.log('Error');
}
};
useEffect(() => {
getData();
}, [])
return (<div>{myData.map((item, index)=>(<div>item.name</div>)}</div>)
}
答:
组件是纯组件,问题很可能出在父组件中。也许某些道具正在更改,从而导致子组件重新渲染。
请记住:如果父组件直接传递子组件,子组件将不会重新渲染,然后触发其生命周期钩子{children}
别忘了 React 严格模式:https://stackoverflow.com/a/60619061/15604836
如果您在本地(从终端/本地主机)运行您的应用程序,则在代码发生更改时,NextJS 会将更改推送到您正在运行的应用程序实例(无论您是否正在积极查看选项卡)。这可能是问题的根源。
在 NextJS v13.4.7 中,React Strict 模式默认处于关闭状态。通过对 useEffect 运行多少次进行一些实验,我可以确认严格模式默认处于关闭状态。app router
转到项目根目录下的文件,您将看到以下内容(您可以在其中打开或关闭它)。next.config.js
// STRICT MODE IS OFF BY DEFAULT
/** @type {import('next').NextConfig} */
const nextConfig = {
};
module.exports = nextConfig;
// STRICT MODE ON - THIS DOES INCREASE TIMES USE EFFECT IS RUN BY 1
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
module.exports = nextConfig;
// STRICT MODE EXPLICITLY OFF - THIS MATCHES THE DEFAULT CASE
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: off,
};
module.exports = nextConfig;
H/T 到引用 React Strict 模式的评论和答案。
你实际上错了,在 next.js 13.4+ 中,在开发模式下默认启用 react strict 模式。你必须让它变成假的,才能像生产一样工作。
https://nextjs.org/docs/app/api-reference/next-config-js/reactStrictMode
评论
Page