简体   繁体   中英

ReactJS: How to get state property of another component?

There is a main component, which uses a menu component. The menu component is using a state property to save the information about selected menu item. But now I need to get the selected module in the main component. How do I do that?

class Main extends Component {
    doSomething(module) {
        console.log(module) // should get 'targetValue'

        // I need to get the info, which module is selected.
        // This info is stored as a state value in the `MainMenu` Component
        // How do I get this information? I can't use the parameter `selectModule` as it is done here.
    }

    render() {
        return (
            <div>
                <MainMenu />
                <Button 
                    onClick={ this.doSomething.bind(this, selectedModule) }
                />
            </div>
        )
    }
}

In this component a menu is generated for each module (of modules array). By clicking on one item, this module is stored into module state variable.

class MainMenu extends Component {
    constructor(props) {
        super(props)
        this.state = { 
            module: 'initialValue'
        }
    }

    selectModule(module) {
        this.setState({ module })
    }

    render() {
        return (
            <Menu>
                <Menu.Item onClick={ this.selectModule.bind(this, 'targetValue') } >
                    { title }
                </Menu.Item>
            </Menu>
        )
    }
}

Instead of doing some magic and examining internal state if children components lift the state to parent. Child becomes stateless.

class Main extends Component {
  state = {
    module: 'initialValue'
  }

  setActiveModule = (module) => {
    this.setState({ module })
  }

  render() {
    return (
      <MainMenu onChange={this.setActiveModule} />
    )
  }
}

class MainMenu extends Component {
  onClick = (module) => () => {
    this.props.onChange(module)
  }

  render() {
    return (
      <Menu>
        <Menu.Item onClick={this.onClick(title)} >
          {title}
        </Menu.Item>
      </Menu>
    )
  }
}

Instead on maintaining the state in MainMenu component, maintain in parent component Main, and pass the module value in props , also pass a function to MainMenu to update the state of parent component Main from child MainMenu.

Write it like this:

class Main extends Component {

    constructor(props) {
        super(props)
        this.state = { 
            module: 'initialValue'
        }
        this.update = this.update.bind(this);
    }

    update(value){
        this.setState({
            module: value
        });
    }

    doSomething(){
        console.log(this.state.module);
    }

    render() {
        return (
            <div>
                <MainMenu module={this.state.module} update={this.update}/>
                <Button 
                    onClick={ this.doSomething.bind(this) }
                />
            </div>
        )
    }
}


class MainMenu extends Component {

    selectModule(module) {
        this.props.update(module);
    }

    render() {
        console.log(this.props.module);
        return (
            <Menu>
                <Menu.Item onClick={this.selectModule.bind(this, 'targetValue') } >
                    { title }
                </Menu.Item>
            </Menu>
        )
    }
}

Sharing state with react is sometimes a bit hard.

The react philosophy tends to say that we have to manage state from top to bottom. The idea is to modify the state in your parent, and pass the informations as props. For example, let's imagine the following scenario :

class Main extends React.Component {
  contructor(props) {
    super(props);
    this.state = { currentMenuSelected: 'Home' };
  }

  onPageChange(newPage) {
    this.setState({ currentMenuSelected: newPage });
  }

  render() {
    return(
      <div>
        <AnotherComponent currentMenu={this.state.currentMenuSelected} />
        <MenuWrapper onMenuPress={this.onPageChange} />
      </div>
    )
  }
}

In my example, we tell the MenuWrapper to use the Main.onPageChange when changing page. This way, we're now able to pass that current selected menu to AnotherComponent using props.

This is the first way to manage state sharing using react, and the default one provided by the library

If you want to manage more complex stuff, sharing more state, you should take a look at the flux architecture https://facebook.github.io/flux/docs/overview.html

and the most common implementation of flux : http://redux.js.org/

Store the menu state in the main component, and pass the state updater down to the menu.

This is quite helpful in getting into top-down state https://facebook.github.io/react/docs/thinking-in-react.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM