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

JavaScript generated form fails to submit

I am currently facing an issue with submitting form data to a PHP file when it is generated using JavaScript. I am unsure of how to resolve this problem. The form submission works fine on a test .html file by itself, but not when it is generated by JavaScr ...

Tips for incorporating multiple classes in Material UI by utilizing the classes props

When using the css-in-js technique to apply classes to a react component, how can I add multiple classes? Below is an example of the classes variable: const styles = theme => ({ container: { display: 'flex', flexWrap: 'wrap&apo ...

Creating variables in Typescript

I'm puzzled by the variable declaration within an Angular component and I'd like to understand why we declare it in the following way: export class AppComponent { serverElements = []; newServerName = ''; newServerContent = &apos ...

Modifying the design of a website in real-time using the EXPRESS.js and NODE.js frameworks

I successfully set up a simple website using node.js and express.js by following this helpful tutorial. My express implementation is structured like this with a jade file for the web interface. // app.js var express = require('express'), r ...

Is there a way to retrieve data from three different Bookshelf.js models in a single query?

Three tables are in my database: User, UserDrink, and VenueDrink Here is a preview of the sample data: User id | name | gender | -------------------- 1 | John | male | 2 | Jane | female | UserDrink id | count | user_id | venue_drink_id 1 | 3 | ...

Bringing in a script and invoking a function on a specific variable

As a newcomer to Typescript, I've been experimenting with some code I came across online to enhance the appearance of links on my website. <script src="https://wow.zamimg.com/widgets/power.js"></script> <script>var wowhead_tooltips ...

The MUI Autocomplete feature does not properly utilize the 'defaultValue' attribute when integrated with the Controller component from react-hook-form

I'm attempting to integrate MUI's Autocomplete with react-hook-form. I've enclosed an Autocomplete component within React Hook Form's Controller. The issue arises when I try to set a defaultValue for the Autocomplete - it doesn't s ...

Is it possible to streamline the restart process in my game and eliminate the extra unnecessary click?

This game requires you to click each image once without clicking one twice. The issue arises when trying to reset the game after all images are clicked. Currently, it requires an extra random click after all 12 images have been clicked in order to render t ...

NextJS - Error: Invalid JSON format, starting with a "<" symbol at position 0

After following a tutorial on NextJS, I attempted to make some modifications. My goal was to include the data.json file on the page. However, I kept encountering the error message "Unexpected token < in JSON at position 0." I understand that I need to con ...

Using a function as an argument to handle the onClick event

I have a function that generates a React.ReactElement object. I need to provide this function with another function that will be triggered by an onClick event on a button. This is how I call the main function: this._createInjurySection1Drawer([{innerDra ...

Intercept Axios Responses - Retrieving API Responses for HTTP Statuses that are not in the 200 range

I've set up a custom Axios instance with interceptors for handling responses. As per the Axios documentation, the success interceptor is triggered for 2xx statuses while the error interceptor handles any other status codes. My goal is to show an error ...

Submitting an image from React and Redux to the backend: A comprehensive guide

I'm currently working with the MERN stack and facing an issue while trying to upload an image in the front end (react) and then access it in the backend (express, nodejs) for later storage. Despite using multer, I keep encountering 'undefined&apo ...

The styled component is not reflecting the specified theme

I have a suspicion that the CSS transition from my Theme is not being applied to a styled component wrapped in another function, but I can't pinpoint the exact reason. I obtained the Basic MUI Dashboard theme from this source and here. Initially, inte ...

Customizing MUI DataGrid: Implementing unique event listeners like `rowDragStart` or `rowDragOver`

Looking to enhance MUI DataGrid's functionality by adding custom event listeners like rowDragStart or rowDragOver? Unfortunately, DataGrid doesn't have predefined props for these specific events. To learn more, check out the official documentati ...

I'm attempting to retrieve information from my vuex store, however, encountering an error in the process

I've encountered an issue with vuex getters while working on my project. I have a route that showcases all users, and upon visiting this route, the AllUsers.vue component is displayed. Within this component, I'm utilizing the UsersList.vue compo ...

Interconnected Dropdown Menus

I've implemented the cascading dropdown jQuery plugin available at https://github.com/dnasir/jquery-cascading-dropdown. In my setup, I have two dropdowns named 'Client' and 'Site'. The goal is to dynamically reduce the list of si ...

Navigating with Vue Router on Internet Information Services (IIS)

I am encountering difficulties understanding why my routes are failing when I refresh my VueJS application hosted on IIS. Everything works fine during normal browsing, but once I press F5 or update view information through a button, a 403 error is thrown. ...

A guide on how to locate a specific marker in react-native-maps using its unique

I've been doing some digging, but I'm struggling to find a solution for extracting the coordinates of a react-native-maps marker based on the provided ID. Unfortunately, I keep encountering an error message that says "undefined is not an object." ...

Experience the power of React with Material Ui and Emoji slider integration

https://i.stack.imgur.com/rnqUq.pnghttps://i.stack.imgur.com/NcZLc.png I am a beginner in React and struggling to achieve the functionality displayed in the image attached. While I have successfully implemented an emoji slider with various facial expressio ...

Make sure to have the list available while choosing an item

I want to design a unique CSS element with the following characteristics: Include a button. When the button is clicked, a list of items (like a dropdown list) should appear. We should be able to select items by clicking on them, and the parent component s ...