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
是否已更改

所以,现在我的问题是:

  • 为什么ESLint抱怨
    userRole
    在 依赖项数组?它甚至不是一个州
  • 为什么ESLint是 抱怨依赖项数组中缺少
    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]);