rksh
rksh

Reputation: 4050

Communicating between React components

I'm new to react so this is something I don't know. In the app that I 'm working with it has a main component where other components are loaded.

Like this,

  render() {
    return (
      <div className="index">
        <HeaderComponent />
        <MainHeroComponent />
        <AboutComponent />
      </div>
    );
  }

And I want when someone clicks a link in HeaderComponent to show the about component. And hide the MainHeroComponent. How can I do such communication between components in React? Is it possibe?

Thanks

Upvotes: 1

Views: 311

Answers (3)

Rajarshi Chakrabarti
Rajarshi Chakrabarti

Reputation: 37

There are various ways you can achieve this, including React-routers and Redux, but since you're new to React, it'll be good if you get familiar with the basics first. For a start, you have to change the state of the main component to decide which child component to render.

In the main component code snippet you posted, initialize a state in the constructor as follows:

/* in the main component */
constructor(props) {
  super(props);
  this.state = {
    showAbout: true
  };
}

Then modify the render function as follows, to pass a reference to your main component, down to your header component:

/* in the main component */
<HeaderComponent mainComponent={this}/>

Then, in HeaderComponent, attach a click event handler to the link on which you want to perform the operation.

/* in HeaderComponent */
<a href="#" ....... onClick={this.showAbout.bind(this)}>Show About</a>

In the same component, define the showAbout function as follows:

/* in HeaderComponent */
showAbout () {
  let mainComponent = this.props.mainComponent;
  mainComponent.setState({
    showAbout: true   
  )};
}

Finally, back in the render function of the main component:

/* in the main component */
render () {
  let mainHeroComponent, aboutComponent;
  if (this.state.showAbout) {
    aboutComponent = (
      <AboutComponent/>
    );
  } else {
    mainHeroComponent = (
      <MainHeroComponent/>
    );
  }

  return (
    <div className="index">
      <HeaderComponent mainComponent={this}/>
      {mainHeroComponent}
      {aboutComponent} 
    </div>
  );
}

And you're done! Basically, a component gets re-rendered every time its state is changed. So each time you click on the link, the main component's state is changed with a new value of showAbout. This will cause the main component to re-render itself, and, based on the value of showAbout, it will decide whether to render MainHeroComponent or AboutComponent.

But you should make sure you have a similar logic to display MainHeroComponent as well, instead of AboutComponent, just to switch the views.

Upvotes: 0

J&#250;lius Retzer
J&#250;lius Retzer

Reputation: 1075

Aditya's answer is probably a better solution, but if you really want to it your way, you can use state and callbacks.

class Index extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showHero: true
    };
    this.toggleShowHero = this.toggleShowHero.bind(this);
  }
  toggleShowHero() {
    this.setState({
      showHero: !this.state.showHero
    });
  }
  render() {
    return (
      <div className="index">
        <HeaderComponent onClick={toggleShowHero}/>
        {
          this.state.showHero ? 
            <MainHeroComponent /> :
            <AboutComponent />
        }
      </div>
    );
}

Upvotes: 0

Aditya Singh
Aditya Singh

Reputation: 16690

Use React-Router and create routes for this scenario instead of direct communication between components. Sample app structure using react-router

const App = React.createClass({
  render() {
    return (
      <div>
        <h1>App</h1>
        <HeaderComponent />
      </div>
    )
  }
})

render((
  <Router>
    <Route path="/" component={App}>
      <Route path="hero" component={MainHeroComponent} />
      <Route path="about" component={AboutComponent} />
    </Route>
  </Router>
), document.body)

For more details on router refer: https://github.com/reactjs/react-router/blob/master/docs/guides/RouteConfiguration.md

Upvotes: 1

Related Questions