Categories
React Answers

How to wait for an async action before route transition with React Router?

Spread the love

Sometimes, we want to wait for an async action before route transition with React Router.

In this article, we’ll look at how to wait for an async action before route transition with React Router.

How to wait for an async action before route transition with React Router?

To wait for an async action before route transition with React Router, we can create our own hook that calls history.push when our action is done.

For instance, we write

export const useBlock = (func) => {
  const { block, push, location } = useHistory();
  const lastLocation = useRef();

  const funcRef = useRef();
  funcRef.current = func;

  useEffect(() => {
    if (location === lastLocation.current || !funcRef.current) {
      return;
    }

    lastLocation.current = location;

    const unblock = block((location, action) => {
      const doBlock = async () => {
        if (!(await funcRef.current(location, action))) {
          unblock();
          push(location);
        }
      };
      doBlock();
      return false;
    });
  }, [location, block, push]);
};

to create the useBlock hook that calls useEffect with a function that calls block if lastLocation.current isn’t the same as location.

In the block callback, we check if the funcRef.current function returns a value

If it’s doesn’t return a value, we call unblock and push to do the navigation.

Then we use it by writing

const Comp = () => {
  useBlock(async (location) => await fetchShouldBlock(location));

  return <span>Hello</span>;
};

to call useBlock with the async function we want to run before navigation.

Conclusion

To wait for an async action before route transition with React Router, we can create our own hook that calls history.push when our action is done.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *