I'm trying to figure out how to notify another component about a state change. Let's say I have 3 components - App.jsx,Header.jsx,and SidebarPush.jsx and all I'm simply trying to do is toggle a class with an onClick.
So the Header.jsx file will have 2 buttons when clicked will toggle the states to true or false. The other 2 components App.jsx and Header.jsx will need to know about these state changes so they can toggle a class whenever those states change.
import React from 'react'; import Header from 'Header'; import classNames from "classnames"; import SidebarPush from 'SidebarPush'; import PageWrapper from 'PageWrapper'; var MainWrapper = React.createClass({ render: function() { return ( <div className={classNames({ 'wrapper': false, 'SidebarPush-collapsed': !this.state.sidbarPushCollapsed })}> <Header/> <SidebarPush/> <PageWrapper> {this.props.children} </PageWrapper> </div> ); } }); module.exports = MainWrapper;
import React from 'react'; import ReactDom from 'react-dom'; class Header extends React.Component { constructor() { super(); this.state = { sidbarPushCollapsed: false, profileCollapsed: false }; this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState({ sidbarPushCollapsed: !this.state.sidbarPushCollapsed, profileCollapsed: !this.state.profileCollapsed }); } render() { return ( <header id="header"> <ul> <li> <button type="button" id="sidbarPush" onClick={this.handleClick} profile={this.state.profileCollapsed}> <i className="fa fa-bars"></i> </button> </li> <li> <button type="button" id="profile" onClick={this.handleClick}> <i className="icon-user"></i> </button> </li> </ul> <ul> <li> <button id="sidbarOverlay" onClick={this.handleClick}> <i className="fa fa-indent"></i> </button> </li> </ul> </header> ); } }; module.exports = Header;
import React from 'react'; import ReactDom from 'react-dom'; import classNames from "classnames"; class SidebarPush extends React.Component { render() { return ( <aside className="sidebarPush"> <div className={classNames({ 'sidebar-profile': true, 'hidden': !this.state.pagesCollapsed })}> .... </div> <nav className="sidebarNav"> .... </nav> </aside> ); } } export default SidebarPush;
There are basically two ways to share state between multiple components: Shift state into a parent component. Store the state externally using React Context or a state framework like Redux.
To use the same state in several components, you have to: Lift the state up to the closest common ancestor. Pass down the state variable and the function to update this state in the props.
Move all of your state and your handleClick
function from Header
to your MainWrapper
component.
Then pass values as props to all components that need to share this functionality.
class MainWrapper extends React.Component { constructor() { super(); this.state = { sidbarPushCollapsed: false, profileCollapsed: false }; this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState({ sidbarPushCollapsed: !this.state.sidbarPushCollapsed, profileCollapsed: !this.state.profileCollapsed }); } render() { return ( //... <Header handleClick={this.handleClick} sidbarPushCollapsed={this.state.sidbarPushCollapsed} profileCollapsed={this.state.profileCollapsed} /> );
Then in your Header's render() method, you'd use this.props
:
<button type="button" id="sidbarPush" onClick={this.props.handleClick} profile={this.props.profileCollapsed}>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With