【问题标题】:React Router's useParams cause useEffect to rerunReact Router 的 useParams 导致 useEffect 重新运行
【发布时间】:2020-02-02 17:59:41
【问题描述】:

我正在使用react-router 5.1 和react 16.10。

对于主从页面,我使用useParams() 从 url 获取 id 以打开当前组的页面。打开发生在useEffect()。因此,id 必须作为该效果的依赖项。但是,当创建一个新组时,如果有足够的数据使组有效,API 会发送该组的 id 并将 URL 设置为 /group/:id。结果,效果再次运行。

function Groups(props) {
  const { id } = useParams();
  const history = useHistory();

  const [group, setGroup] = useState(NEW_GROUP);

  const getData = useCallback(async () => {
    await Promise.resolve(Api.getGroups());
  }, []);

  const getGroup = useCallback(async group => {
    history.push(`/groups/${group.id}`);

    await Promise.resolve(Api.getGroup(group)).then(data => {
      setGroup(data.group);
    });
  }, [getData, history]);

  useEffect(() => {
    getData();

    if (id !== undefined) {
      getGroup({ id });
    }
  }, [props.actions, id, getData, getGroup]);

  // Saving data
  const saveGroup = useCallback(async () => {
    setSaved(SAVING);

    await Promise.resolve(Api.storeGroup(group)).then(data => {
        if (!group.hasOwnProperty('id')) {
            history.push(`/groups/${data.id}`);
            setGroup(prevGroup => ({ ...prevGroup, id: data.id }));
        }

        getData();
        setSaved(SAVED);
    }).catch(() => setSaved(FAILED));
  }, [getData, group, history]);
}

如何在不违反“钩子规则”的情况下防止这种情况发生?

【问题讨论】:

  • 你想让useEffects只在id值改变时运行吗?
  • 我只希望它第一次运行。通常这可以通过将依赖项数组留空来完成,但在这种情况下,这违反了“钩子规则”,我宁愿不包括 ESlin 的规则例外。
  • @Yannick 你解决过这个问题吗?我有完全相同的问题,将 useParams() 用于导致 useEffect 无限循环的对象 id。
  • 我还没有找到合适的解决方案,我们现在根本不更改 URL。不过,这并不理想。

标签: reactjs react-router react-hooks


【解决方案1】:

我遇到了同样的问题,我解决的方法是将 id 从 useParams 传递给函数并仅在 useEffect 中设置 id。

function Groups(props) {
  const { id } = useParams();
  ...

  useEffect(() => {
    getData(id);

    if (id !== undefined) {
      getGroup({ id });
    }
  }, [id]);

 ...
}

【讨论】:

  • 它对我有用,我使用 getGroup(id) 而不是 getGroup({ id });
  • 在“react-router-dom”中相同:“^5.2.0”,我想知道为什么当 id 未定义时 useEffect 看到 id 发生了变化。似乎有些东西在 useParams()...
猜你喜欢
  • 2022-01-12
  • 2021-05-25
  • 2021-07-19
  • 2021-05-10
  • 2020-02-21
  • 1970-01-01
  • 2020-11-21
  • 2021-03-29
  • 2020-11-08
相关资源
最近更新 更多