微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于 props 的 UseEffect 向状态数组添加重复项

如何解决基于 props 的 UseEffect 向状态数组添加重复项

问题的简短描述

用户可以通过 html select tag 选择半径,此值作为 prop 发送到此组件,如果该值更改 useEffect 重新渲染

按照我现在的实施方式,它产生了将 filtered events 添加state 的问题。所以它不断向数组添加重复项。

我如何使用 useEffect / setState 来确保之前的项目将被删除或覆盖,并且只有唯一的事件存储在 state 中?

const [data,setData] = useState();
const [userLat,setUserLat] = useState();
const [userLon,setUserLon] = useState();
const [evtsFiltered,setEvtsFiltered] = useState([]);

// Fetch all events and store in state
useEffect(() => {
  axios.get("http://localhost:5000/events").then((res) => {
    setData(res.data.events);
  });
},[]);

// Filter events based on user's location
useEffect(() => {
  data?.forEach((el) => {
    Geocode.fromAddress(`${el.address}`)
      .then((res) => {
        let dis = getPrecisedistance(
          {
            latitude: parseFloat(res.results[0].geometry.location.lat),longitude: parseFloat(res.results[0].geometry.location.lng),},{ latitude: parseFloat(userLat),longitude: parseFloat(userLon) }
        );
        if (dis / 1000 <= props.radius) { // props.radius will trigger the useEffect when user selects a new value on the homepage
          setEvtsFiltered((evtsFiltered) => [...evtsFiltered,el]);
        }
      })
      .catch((err) => console.log(err));
  });
},[data,userLon,userLat,props.radius]);

我知道 setEvtsFiltered((evtsFiltered) => [...evtsFiltered,el]) 行是错误的,因为我使用 spread operator. 将新事件与以前的事件存储在一起,问题是我不知道如何修复它。

如果有人能指出我正确的方向?

提前致谢!

解决方法

我会将数据映射到一个 Promise 数组,并在使用新数组替换当前状态之前等待所有这些使用 Promise.all() 完成。要删除不符合条件的项目,您可以返回一个空数组,然后使用 Array.flat() 将结果展平以删除它们

示例(未测试):

useEffect(async() => {
  try {
    const evts = await Promise.all(
      data.map(async(el) => {
        const res = await Geocode.fromAddress(`${el.address}`);

        let dis = getPreciseDistance({
          latitude: parseFloat(res.results[0].geometry.location.lat),longitude: parseFloat(res.results[0].geometry.location.lng),},{
          latitude: parseFloat(userLat),longitude: parseFloat(userLon)
        });

        return dis / 1000 <= props.radius ? el : [];
      })
    );

    setEvtsFiltered(evts.flat());
  } catch (e) {
    console.log(err);
  }
},[data,userLon,userLat,props.radius]);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。