使用 setState 防止 useEffect 内部循环

Preventing loop inside useEffect with setState

我想在状态值改变时获取数据。

这是一个简单的方法,因为我可以使用 useEffect 并在状态值更改时告诉它 运行。像这样

useEffect(() => {
  fetch(url,(result) => {
     // this is callback function when data fetched

  });

},[value]);

在我渲染的某处,我在用户单击按钮后调用 setValue

但在我的情况下,value 没有默认值,所以它是 undefined 第一次,我的 API 提供了 value 的初始值。所以第一次 useEffect 也必须设置value

useEffect(() => {
  fetch(url,({value, ...data}) => {
     // this is callback function when data fetched
     setData(data);
     setValue(value); // <- this line make loop since value is an object
    // But I need to set value for initial value that came from server
  });

},[value]);

这会形成一个无限循环,因为我正在根据值更改 value 效果。

简而言之

1-我从 API 电话

中得到了我的初始 value

2-我需要在 value 被用户点击更改后重新调用 API。

这 2 个条件形成了一个无限循环,我该如何处理?

已更新

该值是一个包含年份和月份的对象,其初始值基于数据库中的用户配置。它类似于 {month: 10, year: 2022},用户可以在 UI 中更改它以导航到其他月份。

您可以检查该值是否为“未定义”。如果不是,您可以设置它的值。

像这样:

useEffect(() => {
  fetch(url,({fetchedvalue, ...data}) => {
     // this is callback function when data fetched
     setData(data);
     if (fetchedvalue == undefined){
          setValue(fetchedvalue); // <- this line make loop since value is an object
          // But I need to set value for initial value that came from server
     }
  });

},[value]);

我想在值更改时获取某些内容,我宁愿在用户更改 value 对象时调用一次。

function fetchValue(oldValue) {
  fetch(url, ({ value, ...data }) => {
    setData(data)
    setValue(value)
  })
}

useEffect(() => {
  // initial call to the API
  fetchValue()
}, [])

// Later...
<button onClick={() => {
  const newValue = updateValue(value)
  setValue(newValue)
  fetchValue(newValue)
}} />

或者如果您想使用 useEffect 集中处理效果,您可以从服务器返回的值中拆分 user-local 值:

const [userValue, setUserValue] = useState()
const [serverValue, setServerValue] = useState()

useEffect(() => {
  fetch(url, ({ value, ...data }) => {
    setServerValue(value)
    setData(data)
  })
}, [userValue])

const actualValue = serverValue || userValue

<button onClick={() => {
  setServerValue(undefined)
  setUserValue(updateValue(actualValue))
}} />