为什么在使用上下文 API 获取数据时设置状态会陷入无限获取循环?

Why is Setting state with data in a fetch using context API caught in an infinite fetch loop?

这是我的上下文提供者。在组件中,我获取本地 JSON 数据。 JSON 数据看起来像这样:

[
 {
  "name": "Alan",
  "ticker": [
   "AAPL",
   "MSFT",
   "GOOG",
   "FB"
  ]
 },
 {
  "name": "Madison",
  "ticker": [
    "TSLA",
    "AAPL",
    "V"
  ]
 },
 etc...
]

所以它只是一个对象数组。如果我要控制台日志 resp.json() ,结果会很好。如果我控制日志数据,它将与 objs 数组一起出现。这很好。但是当我尝试使用 setProfile(data) 时,应用程序变得疯狂了。让我向您展示当我尝试使用数据设置配置文件时会发生什么。

我假设这是一个无限获取循环。老实说,当我尝试 setProfile(data) 时,我不确定为什么会发生这种情况。如果有其他方法可以做到这一点,请告诉我。我想要做的就是在配置文件上下文中获取所有配置文件数据,以便我可以在我的其他组件中使用它。例如,我创建了一个下拉列表,显示 json 文件中的所有名称。

您的 useEffect 挂钩缺少依赖项数组,因此它是 运行 每次组件呈现时的回调,即当它更新 profile 状态时。

您可能只想在组件安装时执行一次此提取,因此请使用空的依赖项数组。

useEffect(() => {
  const url = ".....";
  fetch(url)
    .then(resp = resp.json())
    .then(data => setProfile(data))
    .catch(console.log);
}, []);

要向@DrewReese 的正确答案添加更多信息,您可以有效地使用依赖数组来选择何时 'trigger' useEffect。一个空的依赖数组只会在组件挂载时触发,但你可以使用这样的东西:

    const [trigger, setTrigger] = useState(false)
    useEffect(()=>{
        console.log('Hello World')
    }, [trigger])

每次你改变触发器的状态时,以上都会运行。因此,如果您有一个执行此操作的按钮:

    <button onClick={()=>setTrigger(!trigger)}>Log Hello World!</button>

...每次点击都会触发useEffect

考虑useEffect, I also always think it's important to think about useCallback时,它也接受一个依赖数组,可用于将依赖移出useEffect块。