skip to Main Content

Using the data router in React-Router 6 I want to redirect the user from an action, but also I need to return data. Can you do both at the same time?

Redirect works, but no way to send data.

export async function routerAction() {
  return redirect("/some-url");
}

Should work, but does not.

export async function routerAction() {
  return new Response(JSON.stringify({ foo: "bar" }), {
    status: 302,
    headers: {
      "Content-Type": "application/json; utf-8",
      Location: "/some-url",
    },
  });
}

In my component I try to retrieve the data like this:

function SomeComponent() {
  let actionData = useActionData(); // unfortunately, actionData is undefined
}

2

Answers


  1. Seems like you have to find different way to pass data into other component.
    useActionData() only returns the data when you use <Form method="post"> or useSubmit()

    Login or Signup to reply.
  2. Based on this answer it would seem that modern browsers simply ignore the message body of 302 responses.

    As far as I know, all modern browsers ignore the message body of a 302
    in response to a GET or POST and will directly go to the URL as
    specified in Location header.

    What I can suggest then is to just return a JSON response which includes the data and redirect target back to the component submitting the action, then use a useEffect hook to effect an imperative redirect to the target route with the data payload.

    Example:

    import { json } from 'react-router-dom';
    
    const action = ({ request }) => {
      return json({
        data: { foo: "bar" },
        redirect: "/some-url"
      });
    };
    
    const ComponentA = () => {
      const actionData = useActionData();
      const navigate = useNavigate();
    
      useEffect(() => {
        if (actionData) {
          const { data, redirect } = actionData;
          navigate(redirect, { state: data, replace: true });
        }
      }, [actionData, navigate]);
    
      return (
        <>
          ...
          <Form method="post">
            ...
            <button type="submit">Submit</button>
          </Form>
        </>
      );
    };
    

    Instead of using the useActionData hook use the useLocation hook to access the passed route state.

    const SomeComponent = () => {
      const { state } = useLocation();
    
      ...
    };
    

    Demo

    Edit react-router-6-data-router-redirect-with-data

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search