score:1

Accepted answer

i would advice you not to save posts in two places. that somewhat defeats the purpose of using redux. you actually don't need post as a state variable in posts class. whenever there is a new state in redux store associated class will fall into updation cycle.

also, you can have a look at redux-thunk if you are making api calls.

import thunk from 'redux-thunk';
import rootreducer from './reducers/index';

const store = createstore(
  rootreducer,
  applymiddleware(thunk)
);

it will help you move api fetching logic to actions and reducers and thus rendering your views clean.

change this

export const getposts = (posts) => {
    return (dispatch, getstate) => {  
        dispatch({type: get_posts, posts })
        console.log('this works i guess', posts);

    }
}

to

export const getposts = (posts) => {
    return (dispatch, getstate) => {
        axios.get(process.env.react_app_get_posts)
            .then( (res) => {
                 dispatch({type: get_posts, res.data })
             })
        })
    }
}

change this

componentwillmount(){
    this.getposts();
  }

to

componentwillmount(){
    this.props.getposts();
  }

now you wont be needing a componentdidupdate.

also, if you are wondering how to show loading... till the api call is not completed, you can add a key isfetching to your store.

const initialstate = {
    post: [],
    posterror: null,
    posts:[],
    isfecthing: false
}

and can add an action something like changefetchstats

export const getposts = (posts) => {
    return (dispatch, getstate) => {
        dispatch({type: change_state, false});
        axios.get(process.env.react_app_get_posts)
            .then( (res) => {
                 dispatch({type: change_status, true);
                 dispatch({type: get_posts, res.data })
             })
        })
    }
}

score:0

so i finally found a purpose for componentdidupdate

the app took a little bit long to load posts maybe half a second.

so by calling componentdidupdate, i get the posts after its finished rendering.

  componentdidupdate(){
    this.props.getposts(this.state.posts);     
  }

along with another solution by @stevek

change this

 case get_posts:
        return({
            ...state,
            posts: state.posts
        })

to this

import {  get_posts} from '../actions/';

const initialstate = {
    post: [],
    posterror: null,
    posts:[]
}

export default (state = initialstate, action) => {
    switch (action.type) {
        // doesn't get posts
        case get_posts:
            return{...state, posts: action.posts}
        default:
            return state
    }
}

and i can see it after its rendered

enter image description here

score:0

sometimes, it may take time over a network to get a post response. in such case, if ur component gets mounted, it will make a call to the action, but because it takes time, you will get response empty/ undifined posts array. to prevent this from happening, you can go with following :

    componentdidmount(){
this.props.getposts(this.state.posts);

   if(!this.props.posts){
    console.log(this.props.posts);
}

  }

a little tweek in the render method may help too:

render() {
    const {loading, posts} = this.props;
    if (!this.props.isauthenticated) {
      return (<redirect to='/signin' />);
    }
    if(loading){
      return "loading..."
    }
    return (
{ posts &&(
      <div classname="app" style={styles.wrapper}>
        <h1> posts </h1>
        <postlist deletepost={this.ondelete} posts={posts}/>
      </div>
    );)}
  }

Related Query

More Query from same tag