Edper
Edper

Reputation: 9322

Reducer result not reflecting correctly

I have an action dispatcher that picks up comments from a blog post, straight from an API server first then dispatch an action.

export function fetchPostComments(postID) {
 return (dispatch) => {
    fetch(`${url}/posts/${postID}/comments`, { method: 'GET', headers})
    .then((response) => response.json())
    .then((comments) => {console.log("action ", comments); dispatch(getPostComments(comments))})
    .catch((error)=>{console.log('fetch comments error',error)});          
};}

I console.logit as you see above, and it gives the result I am looking for, as shown below.

enter image description here

And here is how I dispatch an action.

export function getPostComments (comments) {
 return {
  type: GET_POST_COMMENTS,
  comments
 }
}

And now here is my reducer:

function comments (state = {}, action) {
 switch (action.type) {
  case GET_POST_COMMENTS:
      console.log("Reducer comments ", action.comments);
      return action.comments;
  default :
      return state
 }
}

If you observe again, I use a console.log to confirm the result and again I have the correct result that I desired as shown below:

enter image description here

Now, in one of my component, I display the blog post information and a link to view comments. Once the user click the view comments, it triggers the calling of the action dispatcher.

 <div className="row">
     <a onClick={this.handleFetchComments} href=""><span className="float-date"><strong style={{fontWeight:'bold'}}>View Comments</strong></span></a>
 </div>
 <div>
      <div>
           <span>Count :  { this.state.comments.length }</span>
      </div>
      <textarea placeholder="Add your comments here"></textarea>
      <input type="submit" value="+Add comment" />        
 </div>

This is the handler to fetch comments:

 handleFetchComments = (e) => {
    e.preventDefault();
    const comments = this.props.getAllComments(this.props.postID);
    console.log("Comments fetch ", comments);
    setInterval(this.loadComments(comments),1000);
 }

 loadComments(comm) {
    console.log("Before ", this.state.comments);
    this.setState(()=>({comments:comm}));
    console.log("After ", this.state.comments);
 }

I put some console.log just to check the result and this is the result which I get, which is wrong and not compatible with the result produced by the reducer a moment ago. It gives me an undefined and empty result from a dispatch action, as shown in the result below:

enter image description here

Meanwhile, my Redux Dev tools every time I clicked the View Comments link, it shows up the correct data that I desired and triggers the dispatch action as shown below.

enter image description here

This is my state by the way on my Component, that has the link to View Comments:

state = {
    post: [],
    hasClickComments : false,
    comments: []
}

This is my mapStateToProps in my App.js:

function mapStateToProps ({posts, comments, categories}) {  
 return {
  posts: posts,
  comments: comments,
  categories: categories,
 }
}

And this is my mapDispatchToProps:

function mapDispatchToProps (dispatch) {
 return {
  getAllComments: (postID) => dispatch(fetchPostComments(postID)),
 }
}

I have other actions that I dispatch also mapDispatchtoProps and it's all working so far, except for this one.

I am new to React and Redux, and I am looking for the solution for this one almost two days but could not figure it out. What could have gone wrong?

Upvotes: 1

Views: 78

Answers (3)

Arun
Arun

Reputation: 113

If your comment data is in redux then might be the problem is the way you are using mapStateToProps. I suggest you to use debugger in function and find what you are getting in state.

function mapStateToProps (state) {  
 debugger
//return {
 // posts: posts,
 // comments: comments,
 // categories: categories,
 //}
}

now look at the data in state on the console. then assign the data to required variables.

Upvotes: 0

simbathesailor
simbathesailor

Reputation: 3687

function comments (state = {}, action) {
 switch (action.type) {
  case GET_POST_COMMENTS:
      console.log("Reducer comments ", action.comments);
      return {
         ...state,
         comments: action.comments;
        }

  default :
      return state
 }
}

Upvotes: 0

menq
menq

Reputation: 391

You mix React Component's State and props.State And Props

after mapStateToProps all the data become the component's props.

and you should use this.props.comments to get your data!

Upvotes: 1

Related Questions