通过路由器参数获取自定义React挂钩

时间:2020-04-13 12:24:23

标签: reactjs fetch react-hooks

我正在尝试根据当前路由器参数使用自定义的React钩子获取数据。

https://stackblitz.com/edit/react-fetch-router

应该做什么:

第一次加载时,检查URL是否包含ID ...

  • 如果确实如此,请获取具有该ID的待办事项
  • 如果没有,则获取具有随机ID的待办事项,然后将ID添加到网址中

在获取按钮上点击...

  • 获取具有随机ID的待办事项并将ID添加到网址

怎么了?

观看控制台或检查器的“网络”选项卡,您可以看到每次点击都会触发多个提取请求-为什么这样做以及应该如何正确完成呢?

1 个答案:

答案 0 :(得分:0)

由于您在handleClick上使用了history.push,因此您将在使用history.push时看到发送了多个请求,这将导致重新渲染并使用随机生成的url并触发fetchTodo功能。

现在将发生重新渲染,这将导致生成随机ID。并传递到useTodo钩子上,这将导致再次调用fetchTodo函数。

正确的解决方案是在handleClick上设置随机的todo id参数,并避免不必要的网址更新

const Todos = () => {
    const history = useHistory();
    const { id: todoId } = useParams();
    const { fetchTodo, todo, isFetching, error } = useTodo(todoId);
  const isInitialRender = useRef(true);

    const handleClick = () => {
    const todoId = randomMax(100);
    history.push(`/${todoId}`);
    };


    useEffect(() => {
        history.push(`/${todoId}`);
    }, []);

  useEffect(() => {
    if(!isInitialRender.current) {
        fetchTodo();
    } else {
      isInitialRender.current = false
    }
  }, [todoId])

    return (
        <>
            <button onClick={handleClick} style={{marginBottom: "10px"}}>Fetch a todo</button>
        {isFetching ? (
          <p>Fetching...</p>
          ) : (
          <Todo todo={todo} color={todo.color} isFetching={isFetching} />
        )
      }
        </>
    );
};

export default Todos;

Working demo

相关问题