Search code examples
reactjstypescriptsetstatesemantic-ui-react

setState does not set the state properly, when dropdown values changes


I am having this scenario, where I have a dropdown which pulls the accounts of a user and then based on its selection the content of the page changes. I am trying an approach which is shown below , It seems like setState does not get invoked properly or may be calling sequence may be wrong. Not really getting what is wrong. Changing drop down value does not update the content .

Help would be appreciated.

import * as React from 'react';
import Select from 'semantic-ui-react/dist/commonjs/addons/Select';

interface IState{
  accountDetails[], // stores all details w.r.t an account
  userAccounts: [], // stores all accounts w.r.t a user
  selectedAccount : string, // selected account from the dropdown
  [x: string] : any,
}

export default class App extends React.Component<{},IState> {

  constructor(props:any){
    super(props);
    this.state = {
      accountDetails: [],
      userAccounts: [],
      selectedAccount: ''
    }
  }

  dropdownChange = (event: React.SyntheticEvent<HTMLElement>, data:any) => {
     this.setState(prevState => ({
      selectedAccount: data.value
     }), () => {});
  }

  async componentDidMount()
  {
      await this.fetchUserAccounts();
  }  


  fetchUserAccounts = async() => {
    //fetch API call for getting all user accounts by passing a user ID
    // I am able to get the data
    fetch('/api/fetch/accounts'
      .then(response => response.json())
      .then(data => this.setState({ userAccounts: data}));
    this.fetchAccountDetails();
  }    

  fetchAccountDetails = async() =>
  {
       let URL = "/api/fetch/account?accountId=" +this.state.selectedAccount;
       fetch('URL'
        .then(response => response.json())
        .then(data => this.setState({ accountDetails: data}));
  }

  render() {
    return(
       <div>
         <Select 
                 options={this.state.userAccounts} 
                 name="selectedAccount"  
                 value={this.state.selectedAccount}
                 onChange={this.dropdownChange}                         
        />
        // component to display the details
        <DetailComponent accounts={this.state.accountDetails} />
      </div>
    )
  }
}

Solution

  • You need to call fetchAccountDetails right after changing the state, for the function to invoke using the latest state that the dropdown has changed:

      dropdownChange = (event: React.SyntheticEvent<HTMLElement>, data:any) => {
         this.setState(prevState => ({
          selectedAccount: data.value
         }), () => { this.fetchAccountDetails() });
      }