I am uplifting a state between two components, and it is working. But when i go into the function that changes my state in the component that catches the data it updates but at the same time goes back to the old state
///COMPONENT THAT THROWS DATA///
import './styles/headerBar.css';
import { useEffect, useState } from 'react';
function HeaderBar(props) {
const [state, set_state] = useState();
const OnClickHandler = () => {
set_state('open');
};
useEffect(() => {
props.throwData(state);
});
return (
<div className="wrapper header_container">
<ul>
<li>
<h1 className={state == 'open' ? 'green' : 'black'}>B</h1>
</li>
<li onClick={OnClickHandler}>
<span class="material-icons md-18">menu</span>
</li>
</ul>
</div>
);
}
export default HeaderBar;
///COMPONENT THAT RETRIEVE THE DATA
import './styles/menuBar.css';
import HeaderBar from './HeaderBar';
import { useEffect, useState } from 'react';
function MenuBar() {
const [actual_class, set_class] = useState();
const Change_class = value => {
set_class(value);
console.log(actual_class);
};
const Close_menu = () => {
set_class(previous_state => {
return 'closed';
});
console.log(actual_class);
};
return (
<div>
<div className={actual_class == 'open' ? 'hide_it' : 'show_it'}>
<HeaderBar throwData={Change_class} />
</div>
<div className="wrapper menu_container">
<h1 onClick={Close_menu}>I'am header bar</h1>
</div>
</div>
);
}
export default MenuBar;
When i run "Close_menu" by clicking in the h1 tag, it turns to the new state, but soon goes back to the old one.
2
Answers
this is a closure over the initial
state
, anduseEffect
is not restrained, it fires after every single render. So after every single render it callsthrowData
with the current/oldstate
.Besides, the entire construct with all the indirections through different states and effects is more complicated than needed. Check this out:
TL;DR: Move the HeaderBar’s state up to the MenuBar.
NL;PR: If you have a child state that updates a parent’s related state, perhaps you don’t need in the child and belongs only to the parent that passes it down.