reactjs - 在使用 graphql 的 useQuery 获取的数据更新 useEffect 钩子内的状态变量时防止无限渲染
问题描述
Graphql 提供了 useQuery 钩子来获取数据。每当组件重新渲染时,它都会被调用。
//mocking useQuery hook of graphql, which updates the data variable
const data = useQuery(false);
我正在使用useEffect挂钩来控制调用“useQuery”的次数。
我想要做的是每当我从 useQuery 接收数据时,我想对数据执行一些操作并将其设置为另一个状态变量“ stateOfValue ”,它是一个嵌套对象数据。所以这必须在 useEffect 挂钩内完成。
因此,我需要添加我的stateOfValue和“ data ”(这有我的 API 数据)变量作为 useEffect 挂钩的依赖项。
const [stateOfValue, setStateOfValue] = useState({
name: "jack",
options: []
});
const someOperation = (currentState) => {
return {
...currentState,
options: [1, 2, 3]
};
}
useEffect(() => {
if (data) {
let newValue = someOperation(stateOfValue);
setStateOfValue(newValue);
}
}, [data, stateOfValue]);
基本上,我将在我的 useEffect 中使用的所有变量添加为依赖项,因为根据 Dan Abramov,这是正确的做法。
现在,根据反应,状态更新必须在没有突变的情况下完成,因为我每次需要更新状态时都会创建一个新对象。但是通过设置一个新的状态变量对象,我的组件被重新渲染,导致无限渲染。
如何以这样一种方式实现它,即我将所有变量传递给我的 useEffect 依赖数组,并让它只执行一次 useEffect。
请注意:如果我不将stateOfValue变量添加到依赖项中,它会起作用,但那将是在撒谎。
解决方案
我认为您误解了您想要在依赖项数组中的内容[data, setStateOfValue]
不是[data, stateOfValue]
. 因为你使用setStateOfValue
not stateOfValue
insideuseEffect
正确的是:
const [stateOfValue, setStateOfValue] = useState({
name: "jack",
options: []
});
const someOperation = useCallback((prevValue) => {
return {
...prevValue,
options: [1, 2, 3]
};
},[])
useEffect(() => {
if (data) {
setStateOfValue(prevValue => {
let newValue = someOperation(prevValue);
return newValue
});
}
}, [data, setStateOfValue,someOperation]);
推荐阅读
- python - 使用 Python Geocoder 时总是得到 None 值
- ruby-on-rails - 如何使用删除功能向用户隐藏数据
- java - 如何解决错误:jarfile 无效或损坏
- ios - Objective-C 中的数据序列化(Avro 替代方案)
- java - 在 maven clean install 期间查找不同版本的组件(来自 pom 中定义的)
- python - Python 请求导致 401 未经授权
- javascript - 如何添加添加行按钮 React?
- javascript - 如何在没有 window.scrollBy(x, y) 的情况下上下滚动 HTML DOM(我需要在一个元素中向下滚动)
- sql - 我想通过在 sql 中的现有值之间插入 0(零)来更新表的列
- windows - Saltstack 对状态变化的操作