J.K*_*.Ko 27 reactjs react-hooks
我是 reactJS 的新手,正在编写代码,以便在从 DB 加载数据之前,它会显示加载消息,然后在加载后,使用加载的数据渲染组件。为此,我同时使用了 useState 钩子和 useEffect 钩子。这是代码:
问题是,当我检查 console.log 时,useEffect 被触发了两次。因此,代码两次查询相同的数据,这是应该避免的。
下面是我写的代码:
import React from 'react';
import './App.css';
import {useState,useEffect} from 'react';
import Postspreview from '../components/Postspreview'
const indexarray=[]; //The array to which the fetched data will be pushed
function Home() {
const [isLoading,setLoad]=useState(true);
useEffect(()=>{
/*
Query logic to query from DB and push to indexarray
*/
setLoad(false); // To indicate that the loading is complete
})
},[]);
if (isLoading===true){
console.log("Loading");
return <div>This is loading...</div>
}
else {
console.log("Loaded!"); //This is actually logged twice.
return (
<div>
<div className="posts_preview_columns">
{indexarray.map(indexarray=>
<Postspreview
username={indexarray.username}
idThumbnail={indexarray.profile_thumbnail}
nickname={indexarray.nickname}
postThumbnail={indexarray.photolink}
/>
)}
</div>
</div>
);
}
}
export default Home;
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我理解为什么它被调用两次,以及如何正确修复代码?非常感谢!
小智 302
从 index.js 中删除 <React.StrictMode> 此代码将是
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)
这
root.render(
<App />
);
Run Code Online (Sandbox Code Playgroud)
React StrictMode 在开发服务器上渲染组件两次
rm_*_*rm_ 65
您很可能在启用了严格模式的开发环境中检查问题。\n要验证情况是否如此,请搜索 <React.StrictMode> 标记并将其删除,或构建生产环境。双重渲染问题应该消失了。\n来自 React 官方文档
\n\n\n\n严格模式可以\xe2\x80\x99t自动为您检测副作用,但它可以通过使副作用更具确定性来帮助您发现它们。这是通过有意两次调用以下函数来完成的:
\n\n
\n- 传递给useState、 useMemo 或 useReducer的函数
\n- [...]
\n
类似的问题在这里我的 React 组件由于严格模式而渲染两次\n
\nTai*_*aig 43
正如其他人已经指出的那样,这种情况的发生很可能是由于React 18.0 中引入的严格模式功能所致。
我写了一篇博文,解释了为什么会发生这种情况以及您可以采取哪些措施来解决它。
但如果您只想查看代码,请看这里:
const initialized = useRef(false)
useEffect(() => {
if (!initialized.current) {
initialized.current = true
// My actual effect logic...
...
}
}, [])
Run Code Online (Sandbox Code Playgroud)
或者作为可重复使用的钩子:
import type { EffectCallback } from "react"
import { useEffect, useRef } from "react"
export function useOnMountUnsafe(effect: EffectCallback) {
const initialized = useRef(false)
useEffect(() => {
if (!initialized.current) {
initialized.current = true
effect()
}
}, [])
}
Run Code Online (Sandbox Code Playgroud)
请记住,只有在绝对必要的情况下才应该采用此解决方案!
Joe*_*oyd 39
可能您还有其他副作用导致组件重新渲染,但 useEffect 本身只会被调用一次。您可以使用以下代码确定地看到这一点。
useEffect(()=>{
/*
Query logic
*/
console.log('i fire once');
},[]);
Run Code Online (Sandbox Code Playgroud)
如果日志“我触发一次”被多次触发,则意味着您的问题是两件事之一。
这个应该很明显,你的组件在页面中出现了几次,每个都会挂载并运行 useEffect
组件被强制卸载并在其初始渲染时重新安装。这可能类似于发生在树更高处的“关键”变化。您需要使用此 useEffect 提升每个级别,直到它仅呈现一次。那么您应该能够找到原因或重新安装。
小智 27
请检查你的index.js
<React.StrictMode>
<App />
</React.StrictMode>
Run Code Online (Sandbox Code Playgroud)
删除 <React.StrictMode> 包装器,您现在应该触发一次
root.render(
<App />
);
Run Code Online (Sandbox Code Playgroud)
小智 26
反应根>index.js>删除<React.StrictMode>包装
小智 25
如果您使用 Next js,请将reactStrictMode从“true”更改为false:
将其添加到您的 next.config.js
reactStrictMode: false,
Run Code Online (Sandbox Code Playgroud)
Riy*_*iya 19
这是ReactJS的特性,而我们使用React.StrictMode。StrictMode 为其后代节点激活额外的检查和警告。因为如果代码中有任何不良实践,应用程序不应该崩溃。我们可以说 StrictMode 是一种安全检查,用于验证组件两次以检测错误。
您将在组件的根部获得此 <React.StricyMode> 。
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)
如果你想限制组件渲染两次,你可以删除<React.StrictMode>并选中它。但有必要用于StrictMode检测运行时错误,以防代码实践不良。
Hem*_*ant 10
我在 React 18 中找到了两次组件安装背后的非常好的解释。UseEffect 在 React 中调用了两次
注意:在生产中,它运行良好。在开发环境的严格模式下,故意添加两次挂载来处理错误和所需的清理。
小智 8
新的 React 文档(目前处于测试版)有一个部分精确描述了这种行为:
\n\n来自文档:
\n\n\n通常,答案是实现清理功能。清理函数应该停止或撤消 Effect 正在执行的任何操作。经验法则是,用户应该\xe2\x80\x99t能够区分运行一次的效果(如在生产中)和设置\xe2\x86\x92清理\xe2\x86\x92设置序列(如你\xe2\x80\x99d 参见开发中)。
\n
所以这个警告应该让你仔细检查你的 useEffect,通常意味着你需要实现一个清理功能。
\n小智 8
React严格模式在开发服务器上渲染组件两次。
因此,您必须从 index.js 中删除 StrictMode。您的 index.js 当前代码如下。
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)
删除 StrictMode 后,它应该如下所示
root.render(
<App />
);
Run Code Online (Sandbox Code Playgroud)
我用这个作为我的替代方案useFocusEffect。我使用了嵌套的反应导航堆栈,例如选项卡和抽屉,并且重构使用useEffect对我来说并不像预期的那样有效。
import React, { useEffect, useState } from 'react'
import { useFocusEffect } from '@react-navigation/native'
const app = () = {
const [isloaded, setLoaded] = useState(false)
useFocusEffect(() => {
if (!isloaded) {
console.log('This should called once')
setLoaded(true)
}
return () => {}
}, [])
}
Run Code Online (Sandbox Code Playgroud)
此外,还有一个例子是您在屏幕上导航两次。
| 归档时间: |
|
| 查看次数: |
36410 次 |
| 最近记录: |