Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React自定义钩子问题-无限依赖循环_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript React自定义钩子问题-无限依赖循环

Javascript React自定义钩子问题-无限依赖循环,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我一直喜欢陷入困境,处理现实世界中出现的所有新的有趣问题:)这里有一个我遇到过几次的问题,我想看看你“应该”如何解决它 概述:我创建了一个自定义钩子来封装我的应用程序的一些业务逻辑,并存储我的一些状态。我在组件中使用自定义挂钩,并在加载时触发事件 问题是:my hook的loadItems功能需要访问myitems以获取最后一个项目的ID。将项添加到我的依赖项数组中会导致无限循环。下面是一个(简化的)示例: 简单项目列表组件 // //简单功能部件 // 从“React”导入React,{use

我一直喜欢陷入困境,处理现实世界中出现的所有新的有趣问题:)这里有一个我遇到过几次的问题,我想看看你“应该”如何解决它

概述:我创建了一个自定义钩子来封装我的应用程序的一些业务逻辑,并存储我的一些状态。我在组件中使用自定义挂钩,并在加载时触发事件

问题是:my hook的
loadItems
功能需要访问my
items
以获取最后一个项目的ID。将
项添加到我的依赖项数组中会导致无限循环。下面是一个(简化的)示例:

简单
项目列表
组件

//
//简单功能部件
//
从“React”导入React,{useffect}
将useItems从“/path/to/custom/hooks/useItems”导入
常量项列表=()=>{
常量{items,loadItems}=useItems()
//在加载时,使用我们的自定义钩子触发API调用
//注意:这就是问题所在。因为在我们的钩子中(下面)
//当项目发生变化时,我们依靠'items'为API设置一些参数
//'loadItems'也将更改,再次触发此'useEffect'调用..并再次:)
useffect(()=>{
loadItems()
},[loadItems])
返回(
    {items.map(item=>
  • {item.text}
  • )}
) } 导出默认项目列表
自定义
useItems
Hook

//
//简单定制挂钩
//
从“react”导入{useState,useCallback}
常量useItems=()=>{
const[items,setItems]=useState([])
//注意:问题的第二部分。因为我使用的是'items'`
//要获取最后一个项的id,我需要将其作为` loadItems'的依赖项提供`
//按linting(和React docs)指令调用。当然,我正在设置项目
//这…所以每次运行它时,它也会更新。
const loadItems=useCallback(()=>{
//抓住我们的最后一件物品
const lastItem=items[items.length-1]
//将该项的id提供给我们的API,以便我们可以分页
常量参数={
itemsAfter:lastItem?lastItem.id:nil
}
//现在点击我们的API并更新我们的项目
返回Api.fetchItems(params).then(response=>setItems(response.data))
},[项目])
返回{items,loadItems}
}
导出默认useItems
代码中的注释应该指出问题所在,但我现在能想到的唯一让linters满意的解决方案是为
loadItems
调用提供参数(例如
loadItems({itemsAfter:…})
),因为数据已经在这个自定义挂钩中,我真的希望不用在我使用
loadItems
功能的任何地方都做

非常感谢您的帮助


Mike

如果计划只运行一次效果,请忽略所有依赖项:

 useEffect(() => {
    loadItems();
 }, []);

您可以尝试使用useReducer,将分派作为loadItems传递,因为它从不更改引用。reducer只关心操作是否为NONE,因为useffect的cleanup函数就是这样清理的

如果action不是NONE,那么state将被设置为项的最后一项,这将触发useffect使用您的api进行获取,当解决此问题时,它将使用setItems来设置项

const NONE = {};
const useItems = () => {
  const [items, setItems] = useState([]);
  const [lastItem, dispatch] = useReducer(
    (state, action) => {
      return action === NONE
        ? NONE
        : items[items.length - 1];
    },
    NONE
  );

  useEffect(() => {
    //initial useEffect or after cleanup, do nothing
    if (lastItem === NONE) {
      return;
    }
    const params = {
      itemsAfter: lastItem ? lastItem.id : Nil,
    };
    // Now hit our API and update our items
    Api.fetchItems(params).then(response =>
      setItems(response)
    );
    return () => dispatch(NONE); //clean up
  }, [lastItem]);
  //return dispatch as load items, it'll set lastItem and trigger
  // the useEffect
  return { items, loadItems: dispatch };
};

在useEffect中,只需将“[loadItems]”替换为“[]”,您只需要在加载时获取,对吗?所以就一次,不再依赖useEffect。你想继续加载项目直到没有更多的项目吗?我不明白
项目
是如何被传递到钩子中的?钩子从哪里获得
项目
?@mattOestreich
加载项目
从服务器加载项目?@jonaswillms我误读了问题和操作代码。我以为OP想向钩子传递一些东西,让钩子获取数据,然后返回数据。相反,钩子所做的只是公开一个“fetch”函数。。。具体来说,Dan说:“但是,删除您使用的依赖项(或盲目指定[])通常是错误的修复方法。”。。有一件事我一直不明白,为什么这么多人建议这样做,而React的一位作者建议不要提供空数组列表。(这也会导致林特错误)。。你能详细解释一下为什么会这样吗?@mattOestreich我不是瞎子。请提出一个更好的解决方案:)这些方案是在钩子击中现实之前写的。@马特:好吧,在这种情况下,它不会咬到你,而且提供的所有解决方案在这里都不起作用。谢谢你抽出时间!我理解OPs的问题并不是和丹的例子一一对应——我完全明白你的意思。我很感激!