为什么在使用上下文 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块。
这是我的上下文提供者。在组件中,我获取本地 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块。