Reactjs 即使存在';重新依赖?为什么埃斯林特会抱怨呢?
考虑以下示例:Reactjs 即使存在';重新依赖?为什么埃斯林特会抱怨呢?,reactjs,react-hooks,use-effect,Reactjs,React Hooks,Use Effect,考虑以下示例: const userRole = sessionStorage.getItem('role'); const { data, setData, type, setTableType } = useTable([]); useEffect(() => { const getData = async () => { // fetch some data from API const fetchedData = await axios('..');
const userRole = sessionStorage.getItem('role');
const { data, setData, type, setTableType } = useTable([]);
useEffect(() => {
const getData = async () => {
// fetch some data from API
const fetchedData = await axios('..');
if (userRole === 'admin') {
setData([...fetchedData, { orders: [] }]);
} else {
setData(fetchedData);
}
if (type === '1') {
setTableType('normal');
}
};
getData();
}, []);
我只想在装载时运行此效果,仅此而已,我不在乎userRole
或setData
是否已更改
所以,现在我的问题是:
userRole
在
依赖项数组?它甚至不是一个州李>
setData
它不是永远都是相同的引用吗,还是会改变//eslint禁用line react hooks/deps
行吗?还是说这太野蛮了类型时。我只想读取初始值并运行useEffect一次如何实现
反应挂钩/详尽的deps警告
Linting是一个分析代码中潜在错误的过程。现在,当我们讨论为什么会出现lint错误时,我们需要了解规则是通过记住特定功能的理想用例来设置的
在这里,对于useEffect钩子,一般的概念是,如果我们有一个可能改变或者可能导致逻辑流改变的值,那么所有这些都应该进入dependencies数组
因此,数据是第一个进入的候选者。userRole的情况类似,因为它被用来控制逻辑流,而不仅仅是作为一个值
我建议使用linter建议忽略错误
用户角色位于useffect
中,因此它是一个依赖项(如果它将更改-useffect
无效)
useffect
不知道它是否相同,这就是它要求依赖关系的原因
通常按照linter的要求执行,并将这两个项添加到依赖项数组中
“但我只想在山上运行它!”你会说。现在,请记住:如果指定deps,则效果使用的组件内部的所有值都必须存在。包括道具、状态、功能——组件中的任何内容
警告:我不建议实际使用这个。这实现了错误的逻辑,并且在值更改时保证是错误的。linter试图提供帮助,因为下面的代码引入了许多微妙的bug。
如果要执行此操作,可以使用存储一次性函数:
constuserrole=sessionStorage.getItem('role');
const{data,setData,type,setTableType}=useTable([]);
const\u dangerousOnMount=useRef(异步()=>{
//从API获取一些数据
const fetchedData=await axios(“..”);
如果(userRole==='admin'){
setData([…fetchedData,{orders:[]}]);
}否则{
设置数据(获取数据);
}
如果(类型=='1'){
可设置类型(“正常”);
}
});
useffect(()=>{
_危险山电流();
}, []);
编辑:在更新以作出反应之后,似乎Eslint已经开始抱怨下面的解决方案,所以我可能会使用/Eslint disable line
如果希望在组件挂载时效果只运行一次,那么给useffect
一个空的依赖项数组是正确的。ESLint警告您的问题是,可能会使用过时的数据执行效果,因为它引用外部状态属性,但正如您所注意到的,如果为数组提供它所要求的依赖项,则每当其中任何一个发生更改时,效果都会运行
幸运的是,有一个简单的解决方案,我很惊讶还没有被提及——将效果包装在useCallback
中。您可以安全地将依赖项赋予useCallback
,而无需再次执行
//某些状态值
const[state,setState]=useState();
const init=useCallback(
() => {
//做一些与国家有关的事情
如果(state==null){}
},
//将依赖项按正常方式传递给数组
[国家]
);
//现在,在没有任何依赖项的情况下执行该效果
useffect(init,[]);
现在,init
将在依赖项更改时重新记忆,但除非您在其他位置调用它,否则实际上只会在下面的useffect
中调用它以执行
要回答您的具体问题:
ESLint抱怨userRole
,因为每个渲染都会重新运行React组件,这意味着userRole
将来可能会有不同的值。您可以通过将userRole
移动到您的函数之外来避免这种情况
与前一种情况相同,尽管setData
实际上可能总是相同的,但它存在更改的可能性,这就是为什么ESLint希望您将其作为依赖项包含的原因。因为它是自定义钩子的一部分,所以不能将它移到函数之外,您可能应该将它包含在依赖项数组中
看到我的主要答案了吗
正如我在前2篇中可能已经解释过的那样,ESLint会怀疑这是一个bug,因为这些值可能会改变,即使它们实际上没有改变。可能只是ESLint没有检查“挂载”效果的特殊情况,因此,如果它像任何其他可能触发多次的效果一样检查该效果,这显然会成为一个现实的bug。一般来说,如果您的效果只运行一次,并且您知道当时的数据是正确的,那么我认为您不需要太担心依赖性警告
如果userRole
发生更改,则
const userRole = sessionStorage.getItem('role');
const { data, setData } = useTable([]);
useEffect(() => {
const getData = async () => {
// fetch some data from API
const fetchedData = await axios('..');
if (userRole === 'admin') {
setData([...fetchedData, { orders: [] }]);
} else {
setData(fetchedData);
}
};
getData();
}, [userRole, setData]);