Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactjs - passing state value from one component to another

I have two components SideNav and Dashboard (two are in different js files). SideNav will have selectbox as filters. I have to pass an array from Dashboard component to Sidebar component. This array has to given as values for select box (which is inside sidenav component).

P.S. What will be the case if I have two different component classes defined in two different JS files. e.g. HomeComponent/Home.js -> Parent component Dashboard/Dashboard.js -> Child component I am making API call on "Home.js" file and getting some data. I want to pass these data to "Dashboard.js" file (component) All the examples I studied, they show two components in the same JS file.

class Dashboard extends Component {
  constructor(props) {
    super(props);
    this.state  = {viz:{},filterData:{}};
  }
  var data1= ['1','2','3'];
  this.setState({data1: data1}, function () {
     console.log(this.state.data1);
  });

 }

//Sidebar

class Sidebar extends Component {

   constructor(props) {
     super(props);
     this.state  = {
       data: ['opt1','opt2']
     };
   }

  handleClick(e) {
    e.preventDefault();
    e.target.parentElement.classList.toggle('open');
    this.setState({data: this.state.data1}, function () {
      console.log(this.state.data);
    });
  }

  render() {

    const props = this.props;
    const handleClick = this.handleClick;

    return (
      <div className="sidebar">
        <nav className="sidebar-nav">
          <Nav>
            <li className="nav-item nav-dropdown">
              <p className="nav-link nav-dropdown-toggle" onClick={handleClick.bind(this)}>Global</p>
              <ul className="nav-dropdown-items">
              <li> Organization <br/>
               <select className="form-control">
                <option value="">Select </option>
                {this.state.data.map(function (option,key) {
                   return <option key={key}>{option}</option>;
                 })}
               </select>
like image 970
sudhashree Avatar asked Sep 26 '17 12:09

sudhashree


2 Answers

If you have to pass state from Dashboard to Sidebar, you have to render Sidebar from Dashboard's render function. Here, you can pass the state of Dashboard to Sidebar.

Code snippet

class Dashboard extends Component {
...
...
  render(){
    return(
    <Sidebar data={this.state.data1}/>
    );
  }
}

If you want the changes made on props (data1) passed to Sidebar be received by Dashboard, you need to lift the state up. i.e, You have to pass a function reference from Dashboard to Sidebar. In Sidebar, you have to invoke it whenever you want the data1 to be passed back to Dashboard. Code snippet.

class Dashboard extends Component {
  constructor(props){
    ...
    //following is not required if u are using => functions in ES6.
    this.onData1Changed = this.onData1Changed.bind(this);
  }
  ...
  ...
  onData1Changed(newData1){
    this.setState({data1 : newData1}, ()=>{
      console.log('Data 1 changed by Sidebar');
    })
  }

  render(){
    return(
    <Sidebar data={this.state.data1} onData1Changed={this.onData1Changed}/>
    );
  }
}

class Sidebar extends Component {
  ...
  //whenever data1 change needs to be sent to Dashboard
  //note: data1 is a variable available with the changed data
  this.props.onData1changed(data1);
}

Reference Doc : https://facebook.github.io/react/docs/lifting-state-up.html

like image 149
Sri Avatar answered Sep 23 '22 20:09

Sri


You can only pass props from parent to child component. Either restructure your components hierarchy to have this dependence, or use a state/event management system like Redux (react-redux) .

like image 40
JulienD Avatar answered Sep 23 '22 20:09

JulienD