title: Reactjs component showing old data
body: <p>I have a component that is supposed to show a list of items. The items are fetched from an API when the component first is loaded, and then the items should be refreshed/replaced when the user clicks a button.</p>
  
  <p>The problem is, my component always seems to be one step behind the user. For example, the first time the user clicks the button the API is called and returns new data, but the component still shows the data it got on initial load. The second time the user clicks, my component shows the data that was returned on the first click. </p>
  
  <p>I'm thinking that the component is reloaded to quick after the button click, so the state isn't updated when the component is displayed, but I have no idea how to solve it?</p>
  
  <p>My component:</p>
  
  <pre><code>import React, {Component} from 'react';
  import {connect} from 'react-redux';
  import {matchesFetchData} from '../actions/matches';
  import Match from './match';
  
  
  class MatchList extends Component {
      constructor(){
          super();
          this.generateNew = this.generateNew.bind(this);
      }  
  
      componentDidMount() {
          this.props.fetchData('http://localhost:4752/api/matches');
      }
  
      render() {
          if (this.props.hasErrored) {
              return &lt;p&gt;Sorry!There was an error loading the items&lt;/p&gt;;
          }
          if (this.props.isLoading) {
              return &lt;p&gt;Loading…&lt;/p&gt;;
          }
  
          return (   
              &lt;div&gt;
                  &lt;nav className="menu"&gt;
                      &lt;input type="number" defaultValue="0" min="0" max="13" ref="safeguards"/&gt;      
                      &lt;button className="generateNew" onClick={this.generateNew}&gt;Ny&lt;/button&gt;         
                  &lt;/nav&gt;
                  &lt;ul className="matchlist"&gt;
                      {this.props.matches.map(function (match, index) {                        
                          return &lt;Match key={index} match={match}/&gt;
                      }) }
                  &lt;/ul&gt;
              &lt;/div&gt;
          )
      }
  
      generateNew(e){
          e.preventDefault();
          const value = this.refs.safeguards.value;
          if(value == 0){
              this.props.fetchData('http://localhost:4752/api/matches');
          }
          else{
              this.props.fetchData('http://localhost:4752/api/matches/' + value);
          }
      }
  }
  
  const mapStateToProps = (state) =&gt; {
      return {
          matches: state.matchesApp.matches,
          hasErrored: state.matchesApp.matchesHasErrored,
          isLoading: state.matchesApp.matchesIsLoading
      };
  };
  
  
  const mapDispatchToProps = (dispatch) =&gt; {
      return {
          fetchData: (url) =&gt; dispatch(matchesFetchData(url))
      };
  };  
  
  export default connect(mapStateToProps, mapDispatchToProps)(MatchList);
  </code></pre>
  
  <p>Actions:</p>
  
  <pre><code>export const MATCHES_HAS_ERRORED = 'MATCHES_HAS_ERRORED';
  export const MATCHES_IS_LOADING = 'MATCHES_IS_LOADING';
  export const MATCHES_FETCH_DATA_SUCCESS = 'MATCHES_FETCH_DATA_SUCCESS';
  
  export function matchesHasErrored(bool){
      return {
          type: MATCHES_HAS_ERRORED,
          hasErrored: bool
      };
  }
  
  export function matchesIsLoading(bool){
      return {
          type: MATCHES_IS_LOADING,
          isLoading: bool
      };
  }
  
  export function matchesFetchDataSuccess(matches){
      return{
          type: MATCHES_FETCH_DATA_SUCCESS,
          matches
      };
  }
  
  export function matchesFetchData(url){
      return (dispatch) =&gt; {
          dispatch(matchesIsLoading(true));
  
          fetch(url)
          .then((response) =&gt; {
              if(!response.ok){
                  throw Error(response.statusText);
              }
  
              dispatch(matchesIsLoading(false));
  
              return response;
          })
          .then((response) =&gt; response.json())
          .then((matches) =&gt; dispatch(matchesFetchDataSuccess(matches)))
          .catch(() =&gt; dispatch(matchesHasErrored(true)));
      }
  }
  </code></pre>
  
  <p>Reducer:</p>
  
  <pre><code>import {MATCHES_HAS_ERRORED, MATCHES_IS_LOADING, MATCHES_FETCH_DATA_SUCCESS} from '../actions/matches';
  
  const initialState = {
      matchesIsLoading: false,
      matchesHasErrored: false,
      matches: []
  }
  
  export function matchesApp(state = initialState, action){
      switch(action.type){
        case MATCHES_HAS_ERRORED:
              return Object.assign({}, state, {
                  matchesHasErrored: action.hasErrored
              });
        case MATCHES_IS_LOADING:
              return Object.assign({}, state, {
                  matchesIsLoading: action.isLoading
              });
        case MATCHES_FETCH_DATA_SUCCESS:
              return Object.assign({}, state, {
                  matchesIsLoading: false,
                  matchesHasErrored: false,
                  matches: action.matches
              });
        default:
              return state;
      }
  }
  </code></pre>
  
  <p>Match component:</p>
  
  <pre><code>import React, {Component} from 'react';
  import {Link} from 'react-router-dom';
  import Result from './result';
  
  class Match extends Component {
      constructor(props){
          super(props);
          this.match = this.props.match;
      }    
  
      render() {
          return (
              &lt;li&gt;
                  &lt;Link to={'/' + this.match.home + '/' + this.match.away}&gt;
                      &lt;span className="matchNumber"&gt;{this.match.number}&lt;/span&gt;
                      &lt;span className="matchup"&gt;
                          {this.match.home} - {this.match.away}
                      &lt;/span&gt;
                      &lt;Result value="1" selected={this.match.homeWin} odds={this.match.percent1}/&gt;&lt;Result value="X" selected={this.match.draw} odds={this.match.percentX}/&gt;&lt;Result value="2" selected={this.match.awayWin} odds={this.match.percent2}/&gt;
                  &lt;/Link&gt;
              &lt;/li&gt;
          )
      }
  }
  
  export default Match;
  </code></pre>