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
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 thechangeStyle
function to theHeader
component.Then in the
Header
you can get theonChangeStyle
function from theprops
and pass it to your button.You should remove the
App
component in theHeader
since this will create a loop sinceHeader
is inApp
and vice versa, this is why your browser "hangs".Adding the
App
component like you did in theHeader
isn’t valid JSX since a React component must return a single node. You could solve this by wrapping each in aReact.Fragment
,<>
, or any other HTML element like adiv
.Doing this though will lead to a render loop since the
App
component is already rendering theHeader
component, so if theHeader
component rendersApp
… 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: