title: React caching my API requests
body: <p>I am having this strange issue where React seems to be caching my API GET requests after I update an course. Just started learning React recently, so lots of new stuff to learn :)</p>
  
  <p>Process:</p>
  
  <p>First, I go to courseList.js, which lists all the courses. Then, I go to courseUpdate.js, which updates a specific course and redirects back to courseList.js</p>
  
  <p>However, after I update a course, I am redirected back to courseList.js  and it outputs old data (prior to my update). I check my API server and see that my React app did not send any requests after the PATCH (update). In my console, I also see that the data is stale, but the timestamp is current. This issue is only occurring when I use         </p>
  
  <pre><code>this.props.router.push('/courses');
  or
  browserHistory.push({pathname: '/courses'});
  </code></pre>
  
  <p>When I use</p>
  
  <pre><code>window.location.href = '/courses';
  </code></pre>
  
  <p>courseList.js loads fresh data as expected.</p>
  
  <p>Any assistance or insights would be appreciated.</p>
  
  <p>Thanks!</p>
  
  <p>courseList.js file:</p>
  
  <pre><code>constructor(props) {
      super(props);
  
      this.state = {
          courses: [],
          loading: true
      };
  
      console.log("Current token: "+sessionStorage.getItem('access_token'));
      console.log("Expires: "+sessionStorage.getItem('access_token_expires'));
  }
  
  componentDidMount() {
      fetchCourses()
          .then((data) =&gt; {
              this.setState(state =&gt; {
                  console.log(new Date().toLocaleString());
                  console.log(data);
                  if(data["error"] === "invalid_grant"){
                      console.log("token expired...redirecting to login");
                      //TODO try to get new token without user redirect
                      this.props.router.push('/login');
                  }else{
                      state.courses = data;
                      state.loading = false;
                      return state;
                  }
  
              })
          })
          .catch((err) =&gt; {
              console.error('err', err);
          });
  }
  
  render() {
      let loading = this.state.loading ? 'loading' : 'loaded';
      return (
          &lt;div&gt;
              &lt;h1&gt;Course list&lt;/h1&gt;
  
              &lt;table className={"table table-hover table-responsive text-center " +loading}&gt;
                  &lt;thead&gt;
                  &lt;tr&gt;
                      &lt;th className="text-center"&gt;id&lt;/th&gt;
                      &lt;th className="text-center"&gt;Department&lt;/th&gt;
                      &lt;th className="text-center"&gt;Course Number&lt;/th&gt;
                      &lt;th className="text-center"&gt;Edit&lt;/th&gt;
                  &lt;/tr&gt;
                  &lt;/thead&gt;
                  &lt;tbody&gt;
                  {this.state.courses &amp;&amp; this.state.courses.map((post, i ) =&gt; {
                      return (
                          &lt;tr key={post.id}&gt;
                              &lt;td&gt;{post.id}&lt;/td&gt;
                              &lt;td&gt;{post.department}&lt;/td&gt;
                              &lt;td&gt;{post.course_number}&lt;/td&gt;
                              &lt;td&gt;
                                  &lt;Link to={`/courses/${post.id}`} className="btn btn-default btn-sm"&gt;Edit&lt;/Link&gt;
                                  &lt;btn onClick={this.deleteHandler.bind(this, post.id)} className="btn btn-danger btn-sm"&gt;Delete&lt;/btn&gt;
                              &lt;/td&gt;
                              &lt;td&gt;
  
                              &lt;/td&gt;
                          &lt;/tr&gt;
                      );
                  })}
  
                  &lt;/tbody&gt;
              &lt;/table&gt;
              &lt;Link to={`/courses/create`} className="btn btn-default btn-sm"&gt;Create course&lt;/Link&gt;
              &lt;br/&gt;
              &lt;small&gt;Page generated on: {new Date().toLocaleString()}&lt;/small&gt;
          &lt;/div&gt;
      );
  }
  </code></pre>
  
  <p>courseUpdate.js</p>
  
  <pre><code>getInitialState() {
      return {
        courses: {}
      };
  },
  
  componentDidMount() {
      fetchCourse(this.props.params.courseId)
        .then((data) =&gt; {
          this.setState(state =&gt; {
            console.log(data)
            if(data["error"] === "invalid_grant"){
              console.log("token expired...redirecting to login");
              //TODO try to get new token without user redirect
              this.props.router.push('/login');
            }else{
              state.courses = data;
              return state;
            }
  
          })
        })
        .catch((err) =&gt; {
          console.error('err', err);
        });
  
      },
      handleSubmit(data) {
          updateCourse(this.state.courses.id, data);
  
          //TODO figure out why window.location redirect works, but router and browserhistory does not
          //this.props.router.push('/courses');
          window.location.href = '/courses';
          /*
          browserHistory.push({
              pathname: '/courses'
          });
          */
      },
      render() {
          return (
              &lt;div&gt;
                  &lt;CourseForm onSubmit={this.handleSubmit}
                      course_number={this.state.courses.course_number}
                      department={this.state.courses.department}
                  /&gt;
              &lt;/div&gt;
          );
      }
  </code></pre>
  
  <p>API Calls:</p>
  
  <pre><code>export function fetchCourses() {
      console.log("Fetching courses");
      return fetch(Config.apiBaseUrl+'/courses', {
          method: 'GET',
          mode: 'cors',
          headers: {
              'Accept': 'application/json',
              'Cache-Control': 'no-cache',
              'Authorization': 'Bearer '+auth.getToken(),
          },
          cache: 'no-cache'
      }).then(res =&gt; res.json())
          .catch(err =&gt; err);
  }
  
  export function updateCourse(id, data){
      return fetch(Config.apiBaseUrl+'/courses/'+id, {
          method: 'PATCH',
          mode: 'cors',
          body: JSON.stringify(data),
          headers: {
              'Accept': 'application/json',
              'Authorization': 'Bearer '+auth.getToken(),
              'Content-Type' : 'application/json'
          }
      }).then(res =&gt; {
          return res;
      }).catch(err =&gt; err);
  }
  </code></pre>