reactjs 如何避免useEffect在使用dispatch()时出现无限循环?

gkl3eglg  于 2023-03-01  发布在  React
关注(0)|答案(3)|浏览(247)

我正在做一个项目,我有一个列表,其中有几个属性。每个属性都有数据,如名称,纬度,经度,等等。
在屏幕的一侧,我绘制了显示属性名称的列表,在屏幕的另一侧,在Map内部,我绘制了一些标记,这些标记相当于每个属性的纬度和经度。
当我在Map上移动时,我希望显示属性名称列表的组件发生变化,只显示Map可见区域内的属性。(与airbnb和其他类似平台的工作方式相同,当我移动Map或放大Map时,属性列表也会更新)
我在useEffect中执行此更新,但在移动贴图时返回以下错误
超出了最大更新深度。当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。
这是我的code

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { setProperties } from "../../store/StoreInfo";

const Properties = () => {
  const dispatch = useDispatch();
  const dataProperties = useSelector((state) => state.storeInfo.dataProperties);
  const mapMoveEnd = useSelector((state) => state.storeInfo.mapMoveEnd);

  React.useEffect(() => {
    if (mapMoveEnd && dataProperties) {
      const _response = dataProperties.filter((accommodation) => {
        return mapMoveEnd
          .getBounds()
          .contains([accommodation.latitude, accommodation.longitude]);
      });
      dispatch(setProperties(_response));
    }
  }, [mapMoveEnd, dispatch, dataProperties]);

  return (
    <div>
      {dataProperties &&
        dataProperties.map((property, index) => (
          <div
            style={{
              display: "flex",
              padding: "10px",
              borderBottom: "1px solid gray"
            }}
            key={`index_${index}`}
          >
            <h3>Name: {property.name}</h3>
          </div>
        ))}
    </div>
  );
};

export default Properties;

我把我的项目放到codesandbox.io中,因为这样更容易理解组件之间的通信方式。如果你打开链接,你会看到当移动Map时,错误随后出现。
提前感谢您的任何帮助!!!

aiazj4mn

aiazj4mn1#

看起来对useEffect的依赖顺序是问题所在,但不确定。
你能试着按以下顺序使用它吗

[mapMoveEnd, dataProperties, dispatch]

这是因为如果您以不同的顺序列出依赖项,react可能无法确定特定值是否已更改。

btqmn9zl

btqmn9zl2#

React.useEffect(() => {
if (mapMoveEnd && dataProperties) {
  const _response = dataProperties.filter((accommodation) => {
    return mapMoveEnd
      .getBounds()
      .contains([accommodation.latitude, accommodation.longitude]);
  });
  dispatch(setProperties(_response));
}
}, [mapMoveEnd, dispatch, dataProperties]);

你的依赖项包含在dispatch(setProperties(_response));中改变的dataProperties。这就是为什么它无限循环的原因。使用useMemo怎么样

const da = useMemo(() => {
let _response = dataProperties;
if (mapMoveEnd && dataProperties) {
  _response = dataProperties.filter((accommodation) => {
    return mapMoveEnd
      .getBounds()
      .contains([accommodation.latitude, accommodation.longitude]);
  });
}
return _response;
}, [dataProperties, mapMoveEnd]);

我试过了,成功了。你可以自己试试。祝你愉快!

k75qkfdt

k75qkfdt3#

当一个组件在useEffect中重复调用setState时,可能会发生这种情况。由于依赖关系,它会创建一个无限循环。从useEffect中删除依赖关系,它将以完美的方式工作。
请尝试以下附加代码:

React.useEffect(() => {
    if (mapMoveEnd && dataProperties) {
      const _response = dataProperties.filter((accommodation) => {
        return mapMoveEnd
          .getBounds()
          .contains([accommodation.latitude, accommodation.longitude]);
      });
      dispatch(setProperties(_response));
    }
  }, [dataProperties]);

相关问题