tuscior
tuscior

Reputation: 99

Updating state after async action in react-redux

The general idea is that someone clicks the button, action fetches data from server and dispatches it. The state is updating and the content on the page is changing. The action looks exacly like that:

     export function getPosts(page){
     return function(dispatch){
      axios.get(`${ROOT_URL}/home?page=${page}`)
          .then(response => {
            dispatch ({
            type: FETCH_POSTS,
            payload: response.data        
          })
          })
          .catch((error) => {
            console.log(error)
          });
    }
    }

Reducer is pretty straightforward:

      export default function(state={}, action){
      switch(action.type){
        case FETCH_POSTS:
        return {posts: action.payload, ...state};
      }
      return state;
    }

And the main page is looking just like that:

    import React, { Component } from 'react';
    import * as actions from '../actions';
    import RequireAuth from './auth/require_auth';
    import { connect } from 'react-redux';
    import { compose } from 'redux';
    class Home extends Component {

    constructor(props) {
      super(props);
      this.state = {
        posts: 'loading....',
      };
      this.props.getPosts();
    }  
    handlePage(){
    console.log(this.props);
    let page = 3;
    this.props.getPosts();
    }

    componentWillReceiveProps(nextProps){
      let posts = nextProps.posts.posts.map((post) => {
      return (<li key={post._id}>{post.date}</li>)
      });
      this.setState({posts: posts});

    }
    shouldComponentUpdate(nextState, nextProps){
    console.log(nextProps.posts, nextState.posts);
    return true;
    }
      render(){
        return(
          <div>
            {this.state.posts}
            <button onClick={this.handlePage.bind(this)}>change something</button>
          </div>
          )
    }
    }

    function mapStateToProps(state){
      return {posts: state.post}
    }

    export default connect(mapStateToProps, actions)(Home);

I was thinking that the state will update in componentWillReciveProps but that is not happening. The data will be fetched after some time so i can't set state just like that. Any idea how to do this ?

Upvotes: 5

Views: 7047

Answers (1)

NonPolynomial
NonPolynomial

Reputation: 329

for async actions, there are two possible ways:

  1. an additional status flag
  2. additional actions

The workflow would like:

  1. Fetching data, dispatch an action, which sets status to 'fetching'
  2. if fetching is successfull, dispatch an action, which sets statusto 'success'
  3. if fecthing fails, dispatch an action, which sets status to 'error'

Further reading: Redux :: Async actions

Upvotes: 3

Related Questions