2

I have a simple app with a few pages, now I would like to change the background color based on page URL using react js,

What is expected?:

When a pathname is /movies I want to change the background to red

Here is what I have so far

 import React 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
`;

Unfortunately, I am getting the following URL

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

What do I need to do this working?

5 Answers 5

1

You should have an extra check to make sure you have set background color or not.Your current code is causing rerender infinte times

 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
`;
Sign up to request clarification or add additional context in comments.

3 Comments

but now I need to refresh to see changes if users navigate to another page URL it's still the same until I refresh the page
Then you need to use a Higher order component in which you pass location and as soon as props change you change the background
Awesome! man this just made my work easier
1

Use an useEffect block so you can perform side-effects effectively.

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

1 Comment

unfortunatelly this works on if I refresh the page , I user navigate to another page url , the color it still the same ,
1

The problem is that you call setMoviesUrlBackgroundColor without wrapping in an effect which results in getting called recursively.

In order to fix this, you just simple set state as needed in this case is your pathname has been changed:

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

7 Comments

unfortunatelly this works on if I refresh the page , I user navigate to another page url , the color it still the same ,
What does the url look like that time?
eg http://127.0.0.1:8001/templates or 127.0.0.1:8001 `
I'm not sure if I get it right as you said the color was still the same. Was it red or green? It's supposed to be green as the path is movies only :)
it just need to change the color based on that route if route is /movies/ theb color is red otherwise green, it works but on when u refresh the page
|
0

Ok, I think I got it, you're creating an infinite loop on your first if statement:

if (getMoviesUrl == '/movies') {
    // every time you change state, that causes your component
    // to re-render, and when it re-renders again you're checking
    // changing your state AGAIN, so it's an infinite loop
    setMoviesUrlBackgroundColor('red');
}

I'll would recommend using react-route for this and getting the url from params, and then update the background color on componentDidMount or useEffect hook when component mounts for the first time, to prevent infinite loops.

Comments

0

Window.location.pathname was resetting state each render, so it needs to be placed within the useEffect hook to prevent re-renders.

Also, this would be a good use-case to pass props to your styled component. Also included this in the code below.

Here's a link to a codesandbox I made with the solution. 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!

1 Comment

unfortunately, this works on if I refresh the page, when user navigate to another page URL, the color is still the same?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.