简体   繁体   中英

React.js Getting State to Immediately Update

I'd like for my state to update changes to immediately be shown when state changes, but I can't seem to figure out why It isn't. Basically when a user clicks on a dropdown item from the menu, the items inner text... that they clicked on should appear as an h1 on the screen, but instead it doesn't appear until the next click. How can I change this? Hopefully I made sense. Code can be found here .

Parent Component (APP):

class App extends React.Component {
  state = {
    loading: true,
    bases: ['USD', 'EUR', 'AUD', 'CAD', 'JPY', 'NZD'],
    selectedBase: null
  };

// When Component Mounts Overlay goes for 3 Seconds

  componentDidMount() {
    setTimeout(() => this.setState({
      loading: false,
    }), 3000)

    this.onBaseChange('USD');
  }

// When User selects a new Base in Search Component, state is updated

  onBaseChange = newBase => {  
    this.setState({ selectedBase: newBase });
  }

// need to find out how to see state change immediatly after its updated!

// Rendered Content:

  render(){
    return (
      <>
      {this.state.loading === false ? (
      <div className="App">
        <div id="one">
          <h1>{this.state.selectedBase}</h1>
          <Search bases = {this.state.bases} selectedBase = {this.state.selectedBase} onBaseChange = {this.onBaseChange}/>
        </div>
       </div>
        ) : (
          <Overlay />
        )}
        </>
    );
  }
}

  

export default App;

Child Component (Search):


class Search extends Component {
    state = {
        dropdownVisible: false,
        term: '',
        selectedBase: this.props.selectedBase
      };

// when a base is clicked from dropdown, the selectedBase is updated, term is set back to empty, and dropdown back to non-visible. // passing state of child up to parent through prop // clearing input search on click

    onBaseSelect = (event) => {
        // when an base is clicked from dropdown, the selectedBase is updated, term is set back to empty, and dropdown back to nonvisible.
        this.setState({
            selectedBase: event.target.innerHTML,
            term: '',
            dropdownVisible: false
        })

        // passing state of child up to parent through prop
        this.props.onBaseChange(this.state.selectedBase)
        
        // clearing input search on click
        document.getElementById("input_search").value = "";
    }
render(){
        return(
                <div id="search">
                        <div id="dropdown" style={{display: this.state.dropdownVisible ? "block" : "none"}}>
                            <ul>
                                {/* filterng out base array based on users input */}
                                {this.props.bases.filter(base => base.includes(this.state.term.toUpperCase())).map((filteredBase, index) => (
                                        <li onClick = {this.onBaseSelect} key={index}>{filteredBase}</li>
                                ))}
                            </ul>
                        </div>
                 </div>
        )
    }
}

export default Search

this.setState is an asynchronous function, so when you do

    // passing state of child up to parent through prop
    this.props.onBaseChange(this.state.selectedBase)
    
    // clearing input search on click
    document.getElementById("input_search").value = "";

the state is not yet updated. So send that code as as a callback to this.setState like this,

 onBaseSelect = (event) => {
    // when an base is clicked from dropdown, the selectedBase is updated, term is set 
     back to empty, and dropdown back to nonvisible.
    this.setState({
        selectedBase: event.target.innerHTML,
        term: '',
        dropdownVisible: false
    },
 ()=>{
     // passing state of child up to parent through prop
    this.props.onBaseChange(this.state.selectedBase)
    
    // clearing input search on click
    document.getElementById("input_search").value = "";
  ); 
}

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