Deke
Deke

Reputation: 4649

conditional rendering of components based on state change

When a user enters a search item, if the data is available, then <Pictures /> is displayed. If the data is not present then <NoResultsFound /> is displayed.By default <NoResultsFound /> state is false and <Pictures /> is true because when the page loads the list of pictures are present. I tried to switch the state like this: this.setState({uisNoResultsFound: true}) and this.setState({uisPictures: false}) throws syntax error. I want this conditional rendering of the UI states within app.js. How to do this?

App.js:

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      uisSearchBarItems: true,
      uisNoResultsFound: false,
      uisPictures: true,
      dsPictures: []
    };
  }


  componentDidMount() {
    unsplash.search.collections("frog", 1, 60)
    .then(toJson)
    .then(json => {
      this.setState({ dsPictures:json.results });
    })
  }


  enteredDatahandler = (ctp) => {
    unsplash.search.collections(ctp, 1, 60)
    .then(toJson)
    .then(json => {
      this.setState({ dsPictures:json.results })
    })

    //******** conditional rendering ***********
    if(this.state.dsPictures.length === 0){
      return (
        this.setState({uisNoResultsFound: true})
        this.setState({uisPictures: false})
      )
    }
    else{
      this.setState({uisNoResultsFound: false})
      this.setState({uisPictures: true})    
    }
    //***********************************

  }




  render() {
    return (
      <div className="App">
        <SearchBarItems ctpEnteredData={this.enteredDatahandler}/>
        <NoResultsFound />
        <Pictures ptcEnteredData={this.state.dsPictures}/>
      </div>
    );
   }
  }

export default App;

searchbaritems.js

class SearchBarItems extends Component {

  enterKeyHandler = (event) => {
    if (event.key === 'Enter'){
        event.preventDefault(); 
        this.props.ctpEnteredData(this.search.value)
    }
  }


 render() {
    return (
        <div>
           <form autoComplete="off" ref={(el) => this.myFormRef = el}>
           <input 
          type="text" 
          name="search" 
          ref={input => this.search = input}
          onKeyPress={this.enterKeyHandler}/>
          </form>
       </div>  
    )
  }
}

Upvotes: 0

Views: 5076

Answers (2)

Ben10
Ben10

Reputation: 498

In your render function you are returning both components, you need to either have if statements or you can do what @Barazu did - which is the most cleanest code.

Github gist: https://gist.github.com/tintinmovie/ed5b4782fa98c3482b561ea3243f98ea

render() {
  if (this.state.uisNoResultsFound === true) {
    return(
      <div className="App">
        <SearchBarItems ctpEnteredData={this.enteredDatahandler}/>
        <NoResultsFound />
      </div>
    );
  }
  else if (this.state.uisPictures === true) {
    return(
      <div className="App">
        <SearchBarItems ctpEnteredData={this.enteredDatahandler}/>
        <Pictures ptcEnteredData={this.state.dsPictures}/>
      </div>
    );
  }
}

Upvotes: 1

Barazu
Barazu

Reputation: 499

Use a ternary expression inside your render method.

{this.state.dsPictures.length === 0 ? <NoResultsFound /> :  <Pictures ptcEnteredData={this.state.dsPictures}/> }

Upvotes: 1

Related Questions