Reactjs useEffect警告缺少导致无限循环的依赖项
以下代码可以完美地工作:Reactjs useEffect警告缺少导致无限循环的依赖项,reactjs,use-effect,Reactjs,Use Effect,以下代码可以完美地工作: import { useState, useEffect } from 'react'; const Main = () => { const [ form, setForm ] = useState({ error: {}, data: {} }); useEffect( () => { async function fetchData() { const promise = await fetch(`
import { useState, useEffect } from 'react';
const Main = () => {
const [ form, setForm ] = useState({
error: {},
data: {}
});
useEffect( () => {
async function fetchData() {
const promise = await fetch(`test.json`);
const result = await promise.json();
const newForm = {...form};
newForm.data = result;
setForm(newForm);
console.log('executed');
}
fetchData();
}, []); // *** I will speak to this [] second argument shortly in question below
return (
<div>
<p>{Object.keys(form.data).length}</p>
</div>
);
};
从'react'导入{useState,useffect};
常量Main=()=>{
const[form,setForm]=useState({
错误:{},
数据:{}
});
useffect(()=>{
异步函数fetchData(){
const promise=wait fetch(`test.json`);
const result=await promise.json();
const newForm={…form};
newForm.data=结果;
setForm(newForm);
console.log('executed');
}
fetchData();
},[]);//***我将在下面讨论第[]个论点
返回(
{Object.keys(form.data).length}
);
};
它所做的一切就是在组件挂载时,获取一个test.json
文件,该文件的内容为{“data”:“hello”}
。这是完美的作品,做什么我想要的
然而,在我的控制台中,我看到编译器抱怨这条消息第20:6行:React Hook useffect缺少依赖项:“form”。包括它或删除依赖项数组react hooks/deps
。当我添加[form]
作为useffect
的第二个参数时,或者如果我从useffect
中删除[]
第二个参数,则useffect
进入无限循环
为什么我的编译器会警告我一个问题,并建议一个导致无限循环的操作?此错误/警告是由您的linter创建的 linter规则假定您遗漏了依赖项数组中
useffect
外部的变量,这将导致意外结果
您可以为以下各项禁用lint规则:
useffect(()=>{
}, []); // eslint禁用管线反应挂钩/详尽的deps
/*eslint禁用react hooks/deps*/
useffect(()=>{
}, []);
setState
回调语法将当前状态作为参数进行切换
import { useState, useEffect } from 'react';
const Main = () => {
const [ form, setForm ] = useState({
error: {},
data: {}
});
useEffect( () => {
async function fetchData() {
const promise = await fetch(`test.json`);
const result = await promise.json();
setForm(currentForm => {
const newForm = {...currentForm};
newForm.data = result;
return newForm;
});
console.log('executed');
}
fetchData();
}, []);
return (
<div>
<p>{Object.keys(form.data).length}</p>
</div>
);
};
控制:
{JSON.stringify(控件,null,“\t”)}
);
};
您可以在这里运行此示例:是您的linter发出了此警告,因为它认为您错过了一个依赖项,事情将以意外的方式运行。您可以禁用lint规则(对于行、文件或所有内容),也可以调整代码使其满意。为了让它满意,您可以使用回调
setState
语法,即setForm(currentForm=>{const newForm={…currentForm};newForm.data=result;return newForm;})
并删除在useffect
中包含form
的需要。我使用了回调语法!
export default function App() {
const [data, setData] = useState({ a: 'Initial Value', b: null });
const [control, setControl] = useState({ a: "Initial Value", b: null });
useEffect(() => {
const asyncFunc = () => {
new Promise(resolve => {
setTimeout(() => resolve(true), 2000)
})
.then(() => {
// The value of "data" will be the initial value from
// when the useEffect first ran.
setData({...data, b: 'Async Updated'});
// The value of "current" wille be the current value of
// the "control" state.
setControl(current => ({ ...current, b: "Async Updated" }));
})
};
asyncFunc();
// Update the data state while the async function has not
// yet been completed.
setData({ a: 'Changed Value', b: null });
// Update the control state while the async function has not
// yet been completed.
setControl({ a: "Changed Value", b: null });
}, []);
// The data value will swap to "Changed Value" and then back
// to "Initial Value" (unexpected) once the async request is
// complete.
// As the control used the current value provided by the
// callback it is able to avoid this issue.
return (
<div>
Data:
<pre>{JSON.stringify(data, null, "\t")}</pre>
Control:
<pre>{JSON.stringify(control, null, "\t")}</pre>
</div>
);
};