Tips for keeping components mounted despite changes in the path

How can I maintain state in React routes to prevent unmounting when switching between them? In my application, it's crucial to keep the state intact during route changes.

When changing routes, the respective components mount and unmount. How can this be prevented?

CODESANDBOX DEMO

I've searched through:

How can I prevent the unmount in React Components?

How can I prevent React from unmounting/remounting a component?

However, none of the solutions seem to work for me.

index.js

import React from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import First from "./routes/First";
import Second from "./routes/Second";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <BrowserRouter>
    <Routes>
      <Route path="" element={<App />} />
      <Route path="first" element={<First />} />
      <Route path="second" element={<Second />} />
    </Routes>
  </BrowserRouter>
);

App.js

import * as React from "react";
import { Link } from "react-router-dom";

export default function App() {
  return (
    <div>
      <h1>Prevent Routing</h1>
      <nav
        style={{
          borderBottom: "solid 1px",
          paddingBottom: "1rem"
        }}
      >
        <Link to="/first">First</Link> |<Link to="/second">Second</Link>
      </nav>
    </div>
  );
}

First.js

import * as React from "react";
import { useEffect } from "react";
import { Link } from "react-router-dom";

export default function First() {
  useEffect(() => {
    console.log("mounted First");

    return () => console.log("unmounted First");
  }, []);

  return (
    <main style={{ padding: "1rem 0" }}>
      <Link to="/">Home</Link>
      <h2>First</h2>
    </main>
  );
}

Second.js

import * as React from "react";
import { useEffect } from "react";
import { Link } from "react-router-dom";

export default function Second() {
  useEffect(() => {
    console.log("mounted Second");

    return () => console.log("unmounted Second");
  }, []);

  return (
    <main style={{ padding: "1rem 0" }}>
      <Link to="/">Home</Link>
      <h2>Second</h2>
    </main>
  );
}

Answer №1

When a component in React Router is not matched by a path, it will be unmounted.


To address this issue, you can combine both components with a double route, allowing each component to determine what to render based on the current path.

This means your main routing setup would look something like:

<Route path={[ '/first', '/second' ]}>
    <First {...{}} />
    <Second {...{}} />
</Route>

You can then use useLocation in the component to toggle the render as needed:

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

function First(props) {

    const location = useLocation();

    if (location.pathname !== '/first') {
        return null
    }
}

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

Locate the final child element within a specified div using JQuery

I am looking to create a web application that allows users to input a question and select from multiple answers. I need to be able to dynamically add extra answer fields when the plus button is clicked, but only within the specific formRow (refer to the co ...

Uncertain about the ins and outs of AJAX

I am a complete beginner in web development. Although I have studied JavaScript and HTML through books, my understanding is still limited. I have never worked with AJAX before and find most online examples too complex for me to follow. My goal is to crea ...

Troubleshooting the issue with UI-Router AngularJS controller not functioning properly in a

Trying to grasp the ins and outs of UI-Router in conjunction with Angular has proven to be quite challenging for me. In my setup, there's an index: <body> <div ui-view></div> <!--Location of file holding app--> <scri ...

Utilize the material-ui dialog component to accentuate the background element

In my current project, I am implementing a dialog component using V4 of material-ui. However, I am facing an issue where I want to prevent a specific element from darkening in the background. While I still want the rest of the elements to darken when the ...

How do you add dynamic content to modals in AngularJS and Angular Strap based on the button that was clicked?

Is there a way to make the buttons in the AngularJS + AngularStrap modal more dynamic? Currently, they display static content, but I would like them to show the content of the first column (first name) of the exact row where the button was clicked. What is ...

"Is there a way to initiate a Date Picker with the current date using Javascript in an AngularJS application

I am having an issue with my date picker where the month starts from the current month and goes up to the next 12 months. However, I only want to display dates from the current date to the last date of the current month. I believe I need to set a limit so ...

Closing tabs in React using Material UI

I am currently working on integrating material ui tabs with a close functionality. I am facing an issue where I cannot set the active tab value in the current tab when closing it, resulting in a warning error. For the code implementation, you can refer to ...

Encountering a problem while attempting to utilize a package that requires the importing of a JSON file for internationalization (

As I integrate a package into my Next.js project (v13.4.3), I encounter an issue with a sub-dependency that provides translations via a JSON file. Upon compilation, the following error occurs: - info Collecting page data ..Error: Cannot find module '/ ...

Using Swig's conditional extend tag with Express.js and Node.js to leverage dynamic content rendering

Is there a way to make the extend tag for the Swig templating engine conditional or able to use a passed variable? Instead of using this code: {% extends '../layouts/layout.view' %} I would prefer to do something like this: {% extends layout ...

When you hover over the page, the content shifts to reveal a hidden div

Trying to figure out how to show additional content when a photo is hovered over without shifting the rest of the page's content placement? Looking for alternative solutions rather than using margin-top: -22%. Here's a link to the website in que ...

Having trouble passing data between view controllers

In my AngularJS application, I have a table column in main.html that is clickable. When clicked, it should redirect to a new customer page with the value of the column cell as the customer's name. There is a corresponding service defined for the app m ...

In JavaScript, private variables are not included in the JSON.stringify output

Imagine creating a class called Rectangle with private fields like width and height, initializing them in the constructor. However, when calling JSON.stringify on an instance of this class, it returns an empty object without including the private members. ...

When using React, I noticed that adding a new product causes its attributes to change after adding another product with different attributes on the same page

Imagine you are browsing the product page for a Nike T-shirt. You select black color and size S, adding it to your cart. The cart now shows 1 Nike T-SHIRT with attributes color: black, size: S. However, if you then switch to white color and size M on the ...

Using MongoDB and NodeJS to retrieve data from a promise

When I make a request to the database using promises, my goal is to extract the values of "latitude" and "longitude" for all documents and store them in an array. This is how I am currently approaching it: const promises = [ dbo.collection("users").f ...

Issue: unhandled exception: Marketplace URI is not valid

It seems like I am the first one in this community to ask a question related to balancedpayments. I recently started working with balancedpayments. Here's what I've done so far: Set up a test marketplace Added a "webhoo ...

Can you explain the functionality of this particular line of code in JavaScript?

As I continue to practice my coding skills, despite still being relatively new, I often come across this type of code in loops when searching for solutions to practice problems. I am intrigued by what exactly this particular line of code is accomplishing. ...

Trying to test a React component using Enzyme? Consider passing your props as events to the

My test is failing because I am unsure of what to include in the onChange attribute value. describe("App", function() { const wrapper = shallow(<App />); it("should contain an input element", function() { expect( wrapper.contains(< ...

How can you reset the inner navigation stack in React-Native?

As someone who is new to react-native, I am currently creating an app with a bottom tab navigation. To achieve this, I have utilized the react-navigation-material-bottom-tabs library, which has been working flawlessly so far. My bottom tab navigator includ ...

Manipulate JSON data structure with JavaScript

The initial JSON data: { "data": { "count_at_hub": [ { "hub": "A", "date": "", "size": "1", "count": 141 }, { "hub": "A", "date": "", "size": " ...

Element that emulates a different element in HTML

Is it possible to have one element that can control and change multiple clone elements, mimicking every change made to the original? While JavaScript & jQuery can easily achieve this, most solutions involve separate variables or instances for each element ...