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

Guide on how to design a schema in Mongoose for uploading arrays of objects in MongoDB

[ const arrayOfObjectsSchema = new Schema({ array: [ { title: { type: String, required: true, }, desc: { type: String, required: true, }, img: { type: String, required: tru ...

A square containing two triangular interactive zones

My goal is to divide a square-shaped div diagonally, creating two triangles. Each triangle should respond to the hover event. However, I have encountered a problem where if you move from one corner of the div directly to the opposite corner, the hover eve ...

Loading Ajax content into div (Wordpress) without pre-loading the font can cause display issues

Currently, I'm implementing a JavaScript function within Wordpress using Ajax to load the content of a post into a modal div when specific elements are clicked. Here is an example of how the JS function appears: function openProjectModal($that) { ...

Add the URL link according to the specific domain name

I am looking for a way to attach additional URL parameters to any links that contain example.com on a webpage. The current script I have only works if the link does not already have parameters attached to it. <script> document.body.innerHTML = d ...

Implementing Dark Mode in Next.js with Material UI using local storage

Having trouble implementing dark mode in a Next.js app with MUI. The issue is that the dark mode settings are not persistent after being set. I am using createContext to manage state as the toggle button is within a component. Upon toggling, the state swi ...

What causes the Material-UI Grid element to shift upon clicking it?

I have encountered an issue while developing a React app with Material UI. The problem arises on a specific page of the application. This particular page consists of text and a button aligned vertically, along with a second set of text and another button ...

A step-by-step guide on ensuring mandatory completion of all input fields prior to form submission

I'm new to JavaScript and I need some help. Currently, I am trying to implement input field validation using pure JavaScript for a form. However, I am facing an issue where the "Required" message only appears next to the last name input. What I want ...

React Context: issue with rendering the component

Within my translation app in React 17.0.1, I encounter an issue with a page consisting of two sections - one for input and the other for translations of that input. The challenge arises when attempting to update the UI after receiving results from a remote ...

Managing state in React for a nested object while still maintaining the data type of the

Exploring the question further from this particular query Updating State in React for Nested Objects The process of updating nested state involves breaking down the object and reconstructing it as shown below: this.setState({ someProperty: { ...this.stat ...

The solution for resolving vue updates using checkboxes

I am currently working on creating a tree view with checkboxes where the parent node's state is always based on its children, including indeterminate values, and v-model it into an array. Here's what I have managed to do so far. The issue arises ...

Are non-local variables in Node.js considered safe to use?

Would it be secure to implement this code in Node.js/Express.js? // using Object.create(null) to avoid key collisions // refer http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/ var theHash = Object.create(null); exports.store = function (req, ...

The issue at hand is why the closure is not functioning properly when variables are assigned to the callback of the getCurrentLocation function

Apologies for the extensive amount of code, but it seems like there may be an issue with AppMobi's getCurrentLocation function in this scenario. The problem arises when tapping on list elements triggers an asynchronous getCurrentLocation call which up ...

Is there a way to retrieve the list element that was added after the HTML was generated?

How can I reference a list element added using the append function in jQuery within my onclick function? See my code snippet below: $(function() { let $movies = $('#showList') let $m = $('#show') $.ajax({ method: 'GET ...

What is the best way to manage a situation where a web element is removed from the DOM while using Selenium Web

On the Sign In page of , I am struggling to extract the value of a label identified by the xpath=".//*[@id='msgIdmmrka']." This particular web element disappears from the DOM a few seconds after entering no email address, a valid password, and cl ...

Determining the type of a single deconstructed variable from an object

My useForm hook is designed to take an object and return several useful functions back, including that object as a state. However, due to TypeScript limitations, the specific type from the initial object cannot be returned because useForm accepts dynamic o ...

The functionality of the Drawer component in material-ui v1.0 seems to be incompatible with TypeScript

Every time I try to utilize Drawer from [email protected] using typescript, I encounter the following error: TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Re ...

Animating shapes in Three.js

Is it possible to animate the underlying shape of a mesh created using Three.js by drawing a shape and extruding it? For example: drawShape: function(){ var shape = new THREE.Shape(); shape.moveTo(0, 0); shape.arc(0,0,30,0,(Math.PI*1.9),true) ...

Personalizing Dialog Title in material-ui

While delving into the world of React and Material-UI, I encountered a challenge in updating the font color in the DialogTitle component. After browsing through various resources, I came across a helpful link that suggested overriding the dialog root class ...

Refreshing knockout viewModel with the mapping plugin is a great way to update the data

I'm attempting to refresh a small widget using knockout and the mapping plugin. Below is the code I have written so far: var AppViewModel = function (data, total, qty) { var self = this; self.Products = ko.mapping.fromJS(data, {}, this); ...

Using the max-width property with Semantic UI Dropdown in ReactJS

I'm struggling to determine how to adjust the max-width of the Dropdown element in ReactJS. I attempted the following: .Menu Dropdown { max-width: 5rem !important; } Unfortunately, this did not work as expected. The dropdowns are taking up too m ...