Search code examples
javascriptreactjsreact-props

How to change props of header dynamically on every page in React?


I am very new to React, I have got a multipage app with a header bar component that is reused on every page.

class Header extends Component {
  render() {
    if (!this.props.authenticated) {
      return null;
    }
    return (
      <header className="topHeader">
        <h1>{this.props.title}</h1>
      </header>
    );
  }
}

export default Header;

I then pass this to App.js (with the title hard coded as "hi" for now):

...return (
      <div className="masterContainer">
        <Router>
          <Header authenticated={this.state.authenticated} title="hi" />
          <Switch>
            <Route
              exact
              path="/login"
              component={() => (
                <LoginPage
                  updateUser={() => this.loadCurrentlyLoggedInUser()}
                />
              )}
            /> ...

In the page component itself, I have a blank page for now:

class Messages extends Component {
  render() {
    return (
      <div className="messages">
        <h2>Test page - Messages</h2>
        <br />
        <h2>This is a private page</h2>
        <p>
          You could only access this page after logged in.
          <br />
          Changes to the token or user logged out will redirect the user to the
          login page.
        </p>
        <br />
      </div>
    );
  }
}

export default Messages;

Now, I want to set a title on the blank page (as title="Messages") but I only know how to pass one prop to another. But I do not know how to have the prop from the blank page, to App.js, then back to the Header component.

Any tips on how I could do that?


Solution

  • You can pass a method handle to your page component as props. And you Page component can callback the handle component.

    There are other advanced ways also like Context API, Redux etc.

    App.js

    state = { title:'' };
    
    setHeaderTitle = (title) => {
     this.setState({ title });
    }
    
    ...return (
          <div className="masterContainer">
            <Router>
              <Header authenticated={this.state.authenticated} title={this.state.title} />
              <Switch>
                <Route
                  exact
                  path="/login"
                  component={() => (
                    <LoginPage setHeaderTitle={this.setHeaderTitle}
                      updateUser={() => this.loadCurrentlyLoggedInUser()}
                    />
                  )}
                /> ...
    
    

    Page component

    class Messages extends Component {
      componentDidMount(){
       this.props.setHeaderTitle("Page Title");
    }
      render() {
        return (
          <div className="messages">
            <h2>Test page - Messages</h2>
            <br />
            <h2>This is a private page</h2>
            <p>
              You could only access this page after logged in.
              <br />
              Changes to the token or user logged out will redirect the user to the
              login page.
            </p>
            <br />
          </div>
        );
      }
    }
    
    export default Messages;