Techniques for Passing Data Between Pages in React Router

Nov 24, 2025 · Programming · 15 views · 7.8

Keywords: React | Router | Data_Passing | State_Management

Abstract: This article explores efficient methods for passing data between pages in React Router. It focuses on using the state mechanism via the <Link> component and history.push() method to transfer data, and accessing it in the target page through location.state. Additionally, it covers version differences and advanced server-side data loading techniques to help developers choose appropriate solutions based on their needs.

Introduction

In React single-page application development, navigation and data passing between pages are common requirements. React Router, as a popular routing library, provides multiple ways to achieve this. This article focuses on analyzing the use of the state mechanism in React Router for passing data between pages and discusses related best practices.

Core Method: Using State to Pass Data

React Router allows passing arbitrary data during navigation through the state property, which can be implemented via the <Link> component or programmatic navigation. First, when using the <Link> component, define a <Link> element in the source component with its to property set to an object containing pathname and state, where state can be any JavaScript value such as an object or array. Second, use the history.push() method; in class components, access the history object through this.props.history and call the push method to pass state. In the target component, data can be accessed via this.props.location.state, ensuring the component is rendered through React Router to receive the location prop.

Code Examples

Based on the Q&A data, assume a data array needs to be passed. The following rewritten code examples demonstrate the implementation of source and target components. The source component uses the history.push() method to pass data, while the target component accesses the data through location.state. Note that in practical applications, the Route component from React Router should be used to define routes.

class ListDetail extends React.Component {
  handleClick(data) {
    console.log(data);
    this.props.history.push({
      pathname: '/detail',
      state: data
    });
  }

  render() {
    const data = [
      { id: 1, name: 'Ford', color: 'Red' },
      { id: 2, name: 'Hyundai', color: 'Blue' }
    ];
    return (
      &lt;div&gt;
        &lt;ul&gt;
          {data.map((item, index) =&gt; (
            &lt;li key={index} onClick={() =&gt; this.handleClick(item)}&gt;
              {item.name}
            &lt;/li&gt;
          ))}
        &lt;/ul&gt;
      &lt;/div&gt;
    );
  }
}
class DetailPage extends React.Component {
  render() {
    const { state } = this.props.location;
    return (
      &lt;div&gt;
        &lt;h3&gt;Detail for {state.name}&lt;/h3&gt;
        &lt;p&gt;Color: {state.color}&lt;/p&gt;
      &lt;/div&gt;
    );
  }
}

Version Differences and Additional Methods

In React Router v6, the use of class components has changed, and functional components with hooks are recommended. For example, use the useNavigate and useLocation hooks to implement data passing. The source component uses the useNavigate hook for programmatic navigation, while the target component uses the useLocation hook to access the passed data. This approach aligns better with modern React development patterns, improving code readability and maintainability.

import { useNavigate } from 'react-router-dom';

function SourceComponent() {
  const navigate = useNavigate();
  const data = { id: 1, name: 'Example' };

  const goToTarget = () =&gt; {
    navigate('/target', { state: data });
  };

  return (
    &lt;button onClick={goToTarget}&gt;Go to Target&lt;/button&gt;
  );
}
import { useLocation } from 'react-router-dom';

function TargetComponent() {
  const location = useLocation();
  const data = location.state;

  return (
    &lt;div&gt;
      &lt;p&gt;Name: {data.name}&lt;/p&gt;
    &lt;/div&gt;
  );
}

Advanced Topics: Server-Side Data Loading

Beyond client-side state passing, React Router supports server-side data loading through loader and clientLoader. This is useful when data needs to be fetched from the server, such as during initial page loads or pre-rendering. The loader function is used for server-side data fetching, while clientLoader is for client-side data fetching and can combine server data. This method offers more robust data management capabilities, suitable for complex application scenarios.

export async function loader({ params }) {
  const product = await fetchProduct(params.id);
  return product;
}

export default function Product({ loaderData }) {
  return (
    &lt;div&gt;
      &lt;h1&gt;{loaderData.name}&lt;/h1&gt;
      &lt;p&gt;{loaderData.description}&lt;/p&gt;
    &lt;/div&gt;
  );
}
export async function clientLoader({ serverLoader, params }) {
  const serverData = await serverLoader();
  const clientData = await fetch(`/api/data/${params.id}`).then(res =&gt; res.json());
  return { ...serverData, ...clientData };
}

Conclusion

In React Router, passing data between pages can be easily achieved through the state mechanism. For client-side navigation, using <Link> or history.push() to pass state is an efficient method. In v6, hooks are recommended to enhance code quality. For complex scenarios, server-side data loading provides more powerful data management capabilities. Developers should choose appropriate methods based on application requirements to ensure reliability and performance in data passing.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.