Tips for Elevating State with React Router Version 6

Looking for advice on sharing state between two routes in my project. I'm debating whether to lift state up from my AddContact component to either the Layout or App components in order to share it with the ContactList. The Layout component simply displays a Header and Outlet component.

function App() {
  const [contacts, setContacts] = useState([])

  return (
    <BrowserRouter>
      <Routes>
        <Route element={<Layout />}>
          <Route path='/' element={<ContactList />} />
          <Route path='/add' element={<AddContact />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

Answer №1

You have the option to lift it to either level.

If you choose to lift state to the App, you can pass necessary data down as props to each routed component.

For instance:

function App() {
  const [contacts, setContacts] = useState([]);

  return (
    <BrowserRouter>
      <Routes>
        <Route element={<Layout />}>
          <Route
            path="/"
            element={<ContactList contacts={contacts} />}
          />
          <Route
            path="/add"
            element={<AddContact setContacts={setContacts} />}
          />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

Alternatively, placing the state in the Layout route component and making it accessible through the Outlet component's context is another approach. The subsequent components would then utilize the provided context value using the useOutletContext hook.

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route element={<Layout />}>
          <Route path="/" element={<ContactList />} />
          <Route path="/add" element={<AddContact />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}
const Layout = () => {
  const [contacts, setContacts] = useState([]);

  return (
    ...
    <Outlet context={{ contacts, setContacts }} />
    ...
  );
};
const ContactList = () => {
  const { contacts } = useOutletContext();

  ...
};
const AddContact = () => {
  const { setContacts } = useOutletContext();

  ...
};

Ultimately, your choice might depend on personal preference or scope, such as the amount of the sub-ReactTree that requires access to the state.

Answer №2

Here's an illustration of utilizing states without using state management systems.

Suppose we have two sibling components: page1 and page2. If we wish to transmit data from the page1 component to the page2 component, hooks in react-router-dom v6 can be employed.

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

const Page1 = () => {
  return (
    <Link to={'/page2'} state: {msg: "hello from page1"}>Go to Page2</Link>
  );
}

export default Page1;

In the page2 component, you can access the object in this manner.

import { useLocation } from "react-router-dom";

const Page2 = (props) => {
   const { state } = useLocation();
   
   return <div>{state.msg}</div>
 
}

export default Page2;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Difficulty in accessing controller data in AngularJS with ng-repeat

I am trying to display comments using ng-repeat in a section, but I am having trouble accessing the data. Even after debugging, I cannot access the data without modifying the controller. I am new to Angular and prone to making mistakes. HTML / JS &apo ...

What is the best way to store a logged-in user's email in a React

I have implemented a login API and I would like to save the email of the logged-in user in the state or another variable, so that I can display it in the header after successful login. The user's email is located in the data.email. The following code ...

The function Router.use() needs a middleware function, but instead, it received an undefined

Attempting to create an authentication app using Node.js, but encountering an error as described in the title. The code for app.js is already set up like this: var createError = require('http-errors'); var express = require('express'); ...

Determine the row index by identifying the row id and table id

I need to retrieve the Index number of a row when a hyperlink is clicked, while also passing additional data from this tag. <a href="javascript:void(0);" onclick="EditDoctorRow(' + RowCountDoctorVisit + ');"> <i class="fa fa-edit"&g ...

Themes in Material UI have properties such as indicatorColor and textColor that define the appearance and

Let's talk about customizing the Tabs component: To start, we import the Tabs component library: <Tabs value={value} indicatorColor="secondary" textColor="secondary" onChange={handleChange} aria-label="status window t ...

mongodb cannot locate the schema method within the nested container

Trying to access a method of a schema stored inside a mixed container has presented a challenge. The scenario is as follows: var CaseSchema = mongoose.Schema({ caseContent : {}, object : {type:String, default : "null"}, collision : {type : Boo ...

I'm struggling to make this background show up in a div

Anyone able to help me figure this out? I can't seem to get the achtergrond_homepage.png as a background in rounded corners. Edit: It seems like the gray color is always on top. Could it be controlled in the JavaScript part? This is the CSS: @ch ...

Switch up image origin when image reaches screen boundary

I am trying to create a DVD screensaver with changing images each time it hits the edge, but I can't seem to get it to work. I've attempted using the code snippet below: var img = document.getElementById("myImage"); img.src = 'img/new-image. ...

Next.js does not support tooltips with custom children components

I created a unique Tooltip component and I'm attempting to include NextLink as the children. However, I encountered an error similar to the one below. Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Tooltip)`. Expected an e ...

Changing a class and audio and storing it using browser's local storage

The challenge I am facing: I am currently working on a feature for my website that allows users to toggle the volume on/off and have that setting persist across different pages. Specifically, I want the user's volume preference to be saved when they n ...

Exploring nested optgroup functionality in React.js

Within my code, I am utilizing a nested optgroup: <select> <optgroup label="A"> <optgroup label="B"> <option>C</option> <option>D</option> <option>G</option> </optg ...

The 'keepMounted' attribute in Material UI Select component is failing to display menu items on the DOM

My main goal is to ensure that my menu items are properly mounted in the DOM for SEO purposes. To achieve this, I am utilizing a MUI Select component for a dropdown navigation and passing in the necessary props like keepMounted, which are then spread on th ...

Integrating Gesture Handling in Leaflet JS for two-finger scrolling enforcement

Have you ever noticed that when you're using a mobile device and scrolling down a webpage with a Google map, the map goes dark and prompts you to "Use two fingers to move the map"? https://i.stack.imgur.com/4HD1M.jpg I am interested in incorporating ...

How to eliminate a particular validator from a form group in Angular

My goal is to eliminate the specific validator from the validator array so that I can reconfigure the controls when certain values have changed. I am aware of the traditional solution where I would need to repeatedly set validators. checked(event: MatC ...

What is the best way to position a component below another component in terms of styling?

Struggling with setting up my React web app using Material-UI. The drawer component is not fitting nicely under the app bar as expected. Despite applying classNames and checking in the console, the styles are not being applied correctly. Currently, the dra ...

What is the method for setting and comparing collectionsjs equality?

I'm interested in utilizing the data structure. Within the factory method, you have the opportunity to specify equals and compare parameters: SortedMap(entries, equals, compare). Can anyone provide insight into what the expected formats for these pa ...

Encountering a PropertyTypeError while attempting to process a payment via Stripe in conjunction with use-shopping-cart on Next.js

Upon reaching the checkout page, I encounter the message: Invalid value with type "undefined" was received for stripe. Valid type for stripe is "string". This issue seems to be related to the redirectToCheckout function. Can someone assist me? The cart-s ...

What could be causing React Router to fail in navigating to a nested route?

In my App.js file, I am implementing front-end routing using react-router-dom version 6.11.2: import "./App.css"; import { Route, RouterProvider, createBrowserRouter, createRoutesFromElements, } from "react-router-dom"; // Othe ...

Attempting to activate template rendering with Meteor session

I'm currently facing an issue with Meteor sessions and how my code is triggering the rendering of a template. At the moment, I have a session that sets its ._id to whatever is clicked. Template.sidebar.events({ /* on click of current sidecat class ch ...

Issues with the visibility of inlined styles within the Angular component library

After developing a custom library with components for an Angular 4 application, I encountered an issue where the CSS styling from the components was not being applied when using them in an application. Although the functionality worked fine, the visual asp ...