skip to Main Content

I basically need to change the background by clicking Power button in component Header:

Header.js

import { Link } from 'react-router-dom';
import { faHome, faBars, faChevronLeft, faPowerOff, faBolt } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import App from '../app/App';
import { useState } from 'react';

const Header = () => {
    const [style, setStyle] = useState("profile-hidden");

    const changeStyle = () => {
      console.log("clicked");
    
      setStyle("profile-displayed");
    };

    return (
        <App style={style} />
        <div class="container-fluid ">           
            <div class="row ">
                <div class="col px-0">
                    <div className="header d-flex justify-content-around">
                        <Link to='/'>
                            <button type="button" class="btn btn-lg img-btn" onClick={setBars}><FontAwesomeIcon icon={faBars} size="xl" /></button>
                        </Link>
                        <Link to='/video'>
                            <button type="button" class="btn btn-lg img-btn" onClick={ChevronLeft}><FontAwesomeIcon icon={faBolt} size="xl" /></button>
                        </Link>
                        <Link to='/video'>
                            <button type="button" class="btn btn-lg img-btn"><FontAwesomeIcon icon={faHome} size="xl"/></button>
                        </Link>
                        <Link to='/video'>
                            <button type="button" class="btn btn-lg img-btn" onClick={changeStyle}><FontAwesomeIcon icon={faPowerOff} size="xl"/></button>
                        </Link>   
                          
                    </div>
                </div>       
            </div>
        </div>
    )
}


export default Header;

index.js

I had to move Router from App.js to index.js otherwise it was giving error You cannot render <Router> inside another <Router>.

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import './index.css';
import App from './components/app/App'

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>
);

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import './app.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import Header from '../header/Header';
import Footer from '../footer/Footer';
import Main from '../pages/main/Main';
import Video from '../pages/video/Video';
import Audio from '../pages/audio/Audio';
import Climate from '../pages/climate/Climate';
import Floorheat from '../pages/floorheat/Floorheat';
import Lights from '../pages/lights/Lights';
import Shades from '../pages/shades/Shades';

const App = (props) => {
  return (
    <div>
      <div className={props.style}> 
        <Header />
        <Routes>
          <Route exact path="/video" element={<Video />}></Route>
          <Route exact path="/" element={<Main />}></Route>
          <Route exact path="/audio" element={<Audio />}></Route>
          <Route exact path="/climate" element={<Climate />}></Route>
          <Route exact path="/floorheat" element={<Floorheat />}></Route>
          <Route exact path="/lights" element={<Lights />}></Route>
          <Route exact path="/shades" element={<Shades />}></Route>
        </Routes>
        <Footer />
      </div>
    </div>
  );
}

export default App;

As soon as I add <App style={style} /> in Header.js browser hangs.
How to pass data to App.js?

2

Answers


  1. As you can see you need your state inside your App component because that is the "highest" component and where you want to use it.

    You can move your state to the App component like so, and pass the changeStyle function to the Header component.

    const App = () => {
      const [style, setStyle] = useState("profile-hidden");
    
      const changeStyle = () => {
        setStyle("profile-displayed");
      };
    
      return (
        <div>
          <div className={props.style}>
            <Header onChangeStyle={changeStyle} />
            ...
            <Footer />
          </div>
        </div>
      );
    };
    

    Then in the Header you can get the onChangeStyle function from the props and pass it to your button.

    You should remove the App component in the Header since this will create a loop since Header is in App and vice versa, this is why your browser "hangs".

    const Header = ({ onChangeStyle }) => {
      return (
        <div class="container-fluid ">
          <div class="row ">
            <div class="col px-0">
              <div className="header d-flex justify-content-around">
                ...
                <Link to="/video">
                  <button
                    type="button"
                    class="btn btn-lg img-btn"
                    onClick={onChangeStyle}
                  >
                    <FontAwesomeIcon icon={faPowerOff} size="xl" />
                  </button>
                </Link>
              </div>
            </div>
          </div>
        </div>
      );
    };
    
    Login or Signup to reply.
  2. Adding the App component like you did in the Header isn’t valid JSX since a React component must return a single node. You could solve this by wrapping each in a React.Fragment, <>, or any other HTML element like a div.

    Doing this though will lead to a render loop since the App component is already rendering the Header component, so if the Header component renders App… this creates an infinite recursive render and the browser will effectively crash.

    Lift the styling state up to a common ancestor component and pass down as props what you need.

    Example:

    const Header = ({ changeStyle }) => {
      return (
        <div class="container-fluid ">           
          <div class="row ">
            <div class="col px-0">
              <div className="header d-flex justify-content-around">
                <Link to='/'>
                  <button
                    type="button"
                    class="btn btn-lg img-btn"
                    onClick={setBars}
                  >
                    <FontAwesomeIcon icon={faBars} size="xl" />
                  </button>
                </Link>
                <Link to='/video'>
                  <button
                    type="button"
                    class="btn btn-lg img-btn"
                    onClick={ChevronLeft}
                  >
                    <FontAwesomeIcon icon={faBolt} size="xl" />
                  </button>
                </Link>
                <Link to='/video'>
                  <button
                    type="button"
                    class="btn btn-lg img-btn"
                  >
                    <FontAwesomeIcon icon={faHome} size="xl" />
                  </button>
                </Link>
                <Link to='/video'>
                  <button
                    type="button"
                    class="btn btn-lg img-btn"
                    onClick={changeStyle}
                  >
                    <FontAwesomeIcon icon={faPowerOff} size="xl" />
                  </button>
                </Link>   
              </div>
            </div>       
          </div>
        </div>
      )
    }
    
    const App = () => {
      const [style, setStyle] = useState("profile-hidden");
    
      const changeStyle = () => {
        console.log("clicked");
        
        setStyle("profile-displayed");
      };
    
      return (
        <div>
          <div className={style}>
            <Header changeStyle={changeStyle} />
            <Routes>
              <Route path="/video" element={<Video />} />
              <Route path="/" element={<Main />} />
              <Route path="/audio" element={<Audio />} />
              <Route path="/climate" element={<Climate />} />
              <Route path="/floorheat" element={<Floorheat />} />
              <Route path="/lights" element={<Lights />} />
              <Route path="/shades" element={<Shades />} />
            </Routes>
            <Footer />
          </div>
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search