Enrique Moreno Tent
Enrique Moreno Tent

Reputation: 25267

A component managing the rendering of another on the same level

I have the following code:

class Header extends Component {
  render() {
    return(
       <ul>
         <li><a onClick={() => this.props.onViewChange('home')}>Home</a></li>
         <li><a onClick={() => this.props.onViewChange('login')}>Login</a></li>
         <li><a onClick={() => this.props.onViewChange('register')}>Register</a></li>
         <li><a onClick={() => this.props.onViewChange('profile')}>Profile</a></li>
       </ul>
    )
  }
}


class App extends Component {
  constructor(props) {
    super(props)
    this.state = ({ view: "home" })
  }

    render()
    {
       return (
         <div className="app">
           <Header onViewChange={(view) => this.setState({ view: view })} />
           <Main view={this.state.view} />
         </div>
       )
    }
}

class Main extends Component {
    constructor(props) {
      super(props)
      this.state = { view: props.view }
    }

    render() {
      switch (this.state.view) {
        case "home":
          return <Home />
        case "login":
          return <Login />
        case "register":
          return <Register />
        case "profile":
          return <Profile />
      }
   }
}

As you can see, I have an <App /> that contains a <Header /> and a <Main />.

<Main> manages which view is being rendered, and <Header /> has the navigation that changes the current view. The way that this code is written will only work, if I add a componentWillReceiveProps to <Main /> but I read that it is an anti pattern, and it is even being deprecated.

What would be a better way to manage this situation?

Notes:

Upvotes: 2

Views: 48

Answers (1)

Giorgi Moniava
Giorgi Moniava

Reputation: 28654

One solution would be just like this:

class Main extends Component {


    render() {
      switch (this.props.view) {
        case "home":
          return <Home />
        case "login":
          return <Login />
        case "register":
          return <Register />
        case "profile":
          return <Profile />
      }
   }
}

You can also pass a callback to <Main/> which would change view state in <App/>. In such case view state would only live in one place, namely in <App/>, and you would not have to duplicate it inside <Main/> as you are doing right now. Because duplicating state is normally not advised and that is what causes the need for componentWillReceiveProps which as you noted is anti pattern.

Upvotes: 1

Related Questions