`Changing the background according to the page URL in React JS: A guide`

Looking to enhance my simple app with a few pages by changing the background color based on page URL using React.js.

What I aim to achieve:

If the pathname is /movies, I want the background color to be red.

This is my current progress:

 import React, { useState } from 'react';

function Testing() {
    const [moviesUrlBackgroundColor, setMoviesUrlBackgroundColor] = useState('green');
    const getMoviesUrl = window.location.pathname;

    if (getMoviesUrl === '/movies') {
        setMoviesUrlBackgroundColor('red');
    } else {
        setMoviesUrlBackgroundColor('green');
    }

    return (
        <div>
            <Container style={{backgroundColor: moviesUrlBackgroundColor}}>
                Testing
            </Container>
        </div>
    );
}

export default Testing;

const Container = styled.div`
    background-color: green;
`;

However, I am encountering the following issue:

app.js:38323 Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop.

How can I resolve this problem and make it work as intended?

Answer №1

It is advisable to add an additional check to ensure that the background color has been properly set in your code. The current implementation is causing an infinite rerender loop.

 import React from 'react'

 function Testing() {
 const[moviesUrlBackgroundColor, setMoviesUrlBackgroundColor] = useState('green');
 const [bgFlag, setbgFlag] = useState(false);


 const getMoviesUrl = window.location.pathname;

 if(!bgFlag){
     setMoviesUrlBackgroundColor(getMoviesUrl == '/movies' ? 'red' : 'green')
     setbgFlag(true)
 }

return (
    <div>
        <Container style={{backgroundColor:moviesUrlBackgroundColor}}>
        
            Testing
        </Container>
    </div>
)
 }

 export default Testing

const Container = styled.div`
    background-color:green
`;

Answer №2

Implementing an useEffect block allows for efficient handling of side-effects.

  useEffect(() => {
    if(getMoviesUrl === '/movies'){
      console.log("execution")
        setMoviesUrlBackgroundColor('red');
    }else{
        setMoviesUrlBackgroundColor('green');
    }
  },[getMoviesUrl]);

Answer №3

The issue arises when you invoke the setMoviesUrlBackgroundColor function without encapsulating it within an effect, leading to a recursive call.

To resolve this issue, simply update the state whenever the pathname changes:

React.useEffect(() => {
  if (getMoviesUrl === '/movies') {
    setMoviesUrlBackgroundColor('red');
  } else {
    setMoviesUrlBackgroundColor('green');
  }
}, [getMoviesUrl])

Answer №4

Ah-ha! I see what's happening here. Looks like you've accidentally created an infinite loop in your first if statement:

if (getMoviesUrl == '/movies') {
    // The issue is that every time the state changes, it triggers a re-render
    // And during each re-render, the state gets changed AGAIN, causing an infinite loop
    setMoviesUrlBackgroundColor('red');
}

My suggestion would be to utilize react-route and fetch the URL from params. Then, update the background color within componentDidMount or useEffect hook when the component mounts for the first time, thus avoiding any potential infinite loops.

Answer №5

Each time the page renders, `window.location.pathname` was causing the state to reset. To avoid unnecessary re-renders, this should be placed inside the `useEffect` hook.

Another suggestion is to pass `props` to your styled component for better customization. I have included an example in the code below.

For a detailed solution, you can check out my codesandbox project: https://codesandbox.io/s/musing-mirzakhani-njmsh?file=/src/random.js:0-620

import React, { useState, useEffect } from "react";
import styled from "styled-components";

const Container = styled.div`
  background: ${(props) => props.backgroundColor || "green"};
`;

const Testing = () => {
  const [moviesUrlBackgroundColor, setMoviesUrlBackgroundColor] = useState(
    "green"
  );

  useEffect(() => {
    const getMoviesUrl = window.location.pathname;
    if (getMoviesUrl === "/movies") {
      setMoviesUrlBackgroundColor("yellow");
    }
  }, [moviesUrlBackgroundColor]);

  return (
    <div>
      <Container backgroundColor={moviesUrlBackgroundColor}>Test</Container>
    </div>
  );
};

export default Testing;

Cheers!

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

Creating a customized image modal in ReactJS that incorporates a dynamic slideshow feature using the

I am attempting to incorporate an image lightbox into my React application: https://www.w3schools.com/howto/howto_js_lightbox.asp Here is the link to the CodeSandbox where I have tried implementing it: https://codesandbox.io/s/reactjs-practice-vbxwt ...

Determining the duration since generating a unique objectid in mongodb

I am currently developing an application that offers users the option to reset their passwords. The process is quite straightforward - after entering his email address, the user will receive a link containing the new objectid number. For example: /reset- ...

Bootstrapvalidator does not function properly with select2.js

My code is not validating the select field. What could be causing this issue? Can anyone provide a solution? Apologies for my poor English, and thank you in advance for your response. Here is my form: <form name="form_tambah" class="form_tambah"> ...

Generate Address from Latitude and Longitude

For my project, I am trying to convert latitude and longitude coordinates into an address. While the Google Maps API is a potential solution, it requires an XML Response which complicates the process. I came across this helpful thread on Stack Overflow d ...

Why is it that a specific variable is only undefined in one specific location within the entire component?

import React from 'react'; import { Formik, Form } from "formik"; import { InputField } from "./formui/InputField"; import { applyGharwapasi } from "../../appollo/applyGharwapasi/applyGharwapasi"; import { useMutatio ...

What is the proper way to define an element's style property in strict mode?

Assuming: const body = document.getElementsByTagName('body')[0]; const iframe = document.createElement('iframe'); iframe.src = protocol + settings.scriptUrl + a; iframe.height = 1; iframe.width = 1; iframe.scrolling = 'no'; ...

employ identical components in v-if and v-else

Currently, I am in the process of designing a login/register page using Vue. The layout includes separate tabs for both login and registration purposes. Here is a snippet of my template code: <transition v-bind:name="TabEffect"> <div ...

Establish the state as the result of a function

I need to update the state of timeToCountdown with the value stored in allTimeInSeconds. Next, I intend to pass this data as a prop to a component. class Timer extends Component { constructor(props){ super(props); this.state = { ...

What is the best way to determine the maximum `width` in a `translateX` animation?

I'm looking to design something similar to a desktop-only carousel. Here's the code snippet I have: <div class="wrapper"> <div class="image-container"> <img alt="Siac" src="https://diey.now.sh/Icons/Clients/SIAC_LOGO.svg"> ...

"Click to view the latest data visualization using the Chart.js

I am exploring ways to enhance the animations in Chart.js for a new web project. The content is organized in tabs, with the chart displayed on the third tab out of four. Currently, the chart animates upon loading. How can I make it so that when #chartTrig ...

Increase the dropdown size without altering the dimensions of the container

I have a dropdown menu enclosed in a div with a vibrant yellow background. Take a look at the code on Plunker here. Upon clicking the dropdown button, the list expands and the container's height increases as well. The background color of the dropdown ...

Guidance on retrieving a boolean value from an asynchronous callback function

I'm looking to determine whether a user is part of a specific group, but I want the boolean value returned in the calling function. I've gone through and debugged the code provided below and everything seems to be working fine. However, since my ...

What is the best way to display "SUCCESS" on the console when a launch is successful, and "ERROR" when it is unsuccessful?

Here is the question: I am delving into Node.js using the Puppeteer library, and I am looking to output "SUCCESS" in the console upon a successful execution, and "ERROR" if it fails. However, I am struggling to grasp how to achieve thi ...

What steps should I take to update the state of this navbar?

Trying to understand why the prop I want to pass won't work with the toggle function: function custToggle({e}){ e.custOrFalse= !e.custOrFalse; var custButton='cust page' if ( e.custOrFalse==true ) { custButton='cust lo ...

What is the best way to position a small square box over each td element containing text using css?

Currently, I am in the process of developing an HTML table where I would like to incorporate a square box around each td element using CSS <tr> <td style="width:8%; text-align:center; border: 1px solid #000; margin-left: 30px;"><?php e ...

Storing data in variables from a single div using Javascript

Within a div element, there lies a number that undergoes constant changes. An example of this is: <div id="current">124</div> A JavaScript function has been implemented to retrieve the data from this specific field and store it in a JavaScrip ...

Here's a guide on how to display the [slug] data on the [slug].js page

I am currently working on developing a logic for my Next.js blog/:post page but I'm encountering some difficulties in the process. The main goal is to: Retrieve the URL (using useRouter) Access the API (a headless CMS) to fetch the post information ...

Retrieve the specified columns as per user-defined filters

Being completely new to JavaScript, I have been assigned the task at hand. The technology stack includes node.js, express, mongodb, and mongoose. Imagine that the database/collection(s) consist of 1000 rows and each row has 50 columns. Some columns may h ...

What is the best way to dismiss the additional modal popup?

Here is an example that I need help with: http://jsfiddle.net/zidski/Mz9QU/1/ When clicking on Link2 followed by Link1, I would like the Link2 box to close automatically. Is there anyone who can assist me with this issue? ...

Combining two arrays of objects using JavaScript

I am working with two arrays of objects that look like this: objects [ { countMedias: 2 }, { countMedias: 1 }, { countMedias: 3 }, { countMedias: 1 }, { countMedias: 2 } ] listePlayliste [ { nom_playlist: 'bbbb' }, { nom_playlist: &apo ...