Passing Data Between Routes in React
In React, passing data between routes can be done in several ways, primarily through React Router. You may want to pass data from one component to another when navigating between routes. This can be achieved through various methods such as URL parameters, query strings, state via the Navigate
component, or even using React Context or global state management libraries (like Redux).
Here’s a breakdown of how to pass data between routes using different techniques in React:
1. Passing Data via URL Parameters
URL parameters are commonly used when you want to pass data between routes that are part of the URL. For example, when navigating to a user’s profile page, you can pass the user ID via the URL.
Example: Passing Data via URL Parameters
- Setting up the Route with Parameters
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
const HomePage = () => {
return (
<div>
<h1>Home Page</h1>
<Link to="/profile/1">Go to User 1's Profile</Link>
</div>
);
};
const ProfilePage = () => {
const { id } = useParams(); // Retrieving the 'id' URL parameter
return <h2>Profile Page for User {id}</h2>;
};
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/profile/:id" element={<ProfilePage />} />
</Routes>
</Router>
);
};
export default App;
Explanation:
- URL Parameters (
/profile/:id
): The:id
is a dynamic segment in the URL that can be accessed through theuseParams
hook. useParams()
: This hook is used to extract the parameters from the URL. For example, theid
parameter passed in the URL (/profile/1
) can be accessed withuseParams()
.
2. Passing Data via Query Strings
Query strings allow you to pass data in a key-value pair format, typically used for optional data. This method is useful for situations like search filters or other non-essential data.
Example: Passing Data via Query Strings
- Setting up the Route with Query Parameters
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom';
const HomePage = () => {
return (
<div>
<h1>Home Page</h1>
<Link to="/profile?id=1&name=JohnDoe">Go to Profile with Query Params</Link>
</div>
);
};
const ProfilePage = () => {
const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const id = queryParams.get('id');
const name = queryParams.get('name');
return <h2>Profile Page for {name} (ID: {id})</h2>;
};
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/profile" element={<ProfilePage />} />
</Routes>
</Router>
);
};
export default App;
Explanation:
- Query String (
?id=1&name=JohnDoe
): The query string in the URL contains the parameters that can be accessed usinguseLocation()
andURLSearchParams
. useLocation()
: This hook provides access to the current location, including the query string. You can then useURLSearchParams
to extract the query parameters.
3. Passing Data via the Navigate
Component (React Router v6+)
React Router v6 introduced the Navigate
component, which allows passing state during navigation. This state is stored in the browser’s history and can be accessed by the target route.
Example: Passing Data via Navigate
- Passing Data Using the
Navigate
Component
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link, useNavigate } from 'react-router-dom';
const HomePage = () => {
const navigate = useNavigate();
const goToProfile = () => {
navigate('/profile', { state: { id: 1, name: 'JohnDoe' } });
};
return (
<div>
<h1>Home Page</h1>
<button onClick={goToProfile}>Go to Profile with State</button>
</div>
);
};
const ProfilePage = () => {
const location = useLocation();
const { id, name } = location.state || {};
return <h2>Profile Page for {name} (ID: {id})</h2>;
};
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/profile" element={<ProfilePage />} />
</Routes>
</Router>
);
};
export default App;
Explanation:
- Passing State with
navigate()
: Thenavigate
function is used to navigate to a new route, and the second argument allows you to pass state along with the navigation. - Accessing State with
location.state
: In the target route (ProfilePage
), you can access the passed state vialocation.state
.
4. Using React Context for Global Data Sharing
For more complex data passing scenarios (e.g., sharing data between routes without repeatedly passing props), you can use React Context to create a global state that can be accessed by any component in the component tree, including those in different routes.
Example: Passing Data with React Context
- Creating the Context
import React, { createContext, useContext, useState } from 'react';
const UserContext = createContext();
const UserProvider = ({ children }) => {
const [user, setUser] = useState({ id: 1, name: 'JohnDoe' });
return (
<UserContext.Provider value={user}>
{children}
</UserContext.Provider>
);
};
const useUser = () => useContext(UserContext);
export { UserProvider, useUser };
- Using Context in Routes
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import { UserProvider, useUser } from './UserContext';
const HomePage = () => {
return (
<div>
<h1>Home Page</h1>
<Link to="/profile">Go to Profile</Link>
</div>
);
};
const ProfilePage = () => {
const user = useUser(); // Accessing user data from context
return <h2>Profile Page for {user.name} (ID: {user.id})</h2>;
};
const App = () => {
return (
<UserProvider>
<Router>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/profile" element={<ProfilePage />} />
</Routes>
</Router>
</UserProvider>
);
};
export default App;
Explanation:
UserContext
: A context that holds user data, which can be accessed by any component wrapped with theUserProvider
.useUser()
: Custom hook to access the user data from the context.
5. Using Local Storage or Session Storage for Data Persistence
For more persistent data across sessions (or page reloads), you can store data in localStorage
or sessionStorage
and retrieve it from another route.
Example: Passing Data Using localStorage
- Saving Data in
localStorage
const goToProfile = () => {
localStorage.setItem('user', JSON.stringify({ id: 1, name: 'JohnDoe' }));
navigate('/profile');
};
- Retrieving Data in the Target Route
const ProfilePage = () => {
const user = JSON.parse(localStorage.getItem('user'));
return <h2>Profile Page for {user.name} (ID: {user.id})</h2>;
};
Explanation:
localStorage
: Data stored inlocalStorage
persists even after the page reloads. You can store an object as a string usingJSON.stringify()
and retrieve it withJSON.parse()
.