简体   繁体   中英

Unable to access Redux state in React component

I am trying to display the redux state into my react component.My root reducer looks this:

index.js

import { combineReducers } from 'redux';
import PostReducer from './PostsReducer';
import { reducer as formReducer} from 'redux-form';
import CategoriesReducer from './CategoriesReducer';
import CommentsReducer from './CommentsReducer';

const rootReducer = combineReducers({
    posts: PostReducer,
    categories: CategoriesReducer,
    comments: CommentsReducer,
    form : formReducer
});

export default rootReducer;

Now,I am facing issues in accessing my comments state.My CommentsReducer reducer is as shown below:

CommentsReducer.js

import { FETCH_COMMENTS } from '../actions/comment_action';

export default function(state={}, action) {
    switch (action.type) {
      case FETCH_COMMENTS:
          return {comments: {...state.comments, ...action.payload.data}};

      default:
        return state;
    }
}

In my component,I am trying to get the state in my mapStateToProps method as follows:

function mapStateToProps({ posts, comments }, ownProps) {
    return {
      post: posts[ownProps.match.params.id],
      comment: comments[ownProps.match.params.id]};
}

Now, in my render function if I try to get the comments state as {this.props.comments} , I receive null.I mean it does not display anything.How do I proceed?

EDIT 1: Adding screenshot of the state: 州

EDIT 2 Conditional rendering:

{
            (createStoreWithMiddleware.getState().comments) ?

              <div>
                  {this.props.comment}
              </div>
                                                  :
              <div>
                Null
              </div>

          }

EDIT 3 : Comment.js file in the api server.

const defaultData = {
  "894tuq4ut84ut8v4t8wun89g": {
    id: '894tuq4ut84ut8v4t8wun89g',
    parentId: "8xf0y6ziyjabvozdd253nd",
    timestamp: 1468166872634,
    body: 'Hi there! I am a COMMENT.',
    author: 'thingtwo',
    voteScore: 6,
    deleted: false,
    parentDeleted: false
  },
  "8tu4bsun805n8un48ve89": {
    id: '8tu4bsun805n8un48ve89',
    parentId: "8xf0y6ziyjabvozdd253nd",
    timestamp: 1469479767190,
    body: 'Comments. Are. Cool.',
    author: 'thingone',
    voteScore: -5,
    deleted: false,
    parentDeleted: false
  }
}

And my API endpoint is described as shown below:

GET /comments/:id
      USAGE:
        Get the details for a single comment

EDIT 4 Screenshot of the output. devtools

Since you have used "comment" in your mapStateToProps.

You can access it using {this.props.comment} and not {this.props.comments}

Let me know if this helps.

You have to import connect method from react-redux then use mapStateToProps into connect method like:

      import { connect } from 'react-redux';
      class ComponentName extends Component {
      }
      function mapStateToProps({ posts, comments }, ownProps) {
        return {
            post: posts[ownProps.match.params.id],
            comment: comments[ownProps.match.params.id]};
      }  
      export default connect(mapStateToProps)(ComponentName);

There are a few things that you need to check

First: The below reducer is a comment reducer and state.comments is not defined so ...state.comments will fail. So you need to update the initialState like state = {comments: {}}

import { FETCH_COMMENTS } from '../actions/comment_action';

export default function(state = {comments: {}}, action) {
    switch (action.type) {
      case FETCH_COMMENTS:
          return {comments: {...state.comments, ...action.payload.data}};

      default:
        return state;
    }
}

Second: In mapStateToProps function mapStateToProps({ posts, comments }, ownProps) { posts and components are reducers and hence posts[ownProps.match.params.id] and comments[ownProps.match.params.id] is not what you want but

function mapStateToProps({ posts, comments }, ownProps) {
    return {
      post: Object.values(posts.posts).find(post => post.id ===ownProps.match.params.id),
      comment: Object.values(comments.comments).find(comment => comment.id ===ownProps.match.params.id};
}

Third: Now that comments are updated using fetchComments action, you should make a check for comment before using it in the component like

if(this.props.comment) {
    //do what you want with comment here
}

or if you are using it in JSX, use it like

{this.props.comment ? <div>{this.props.comment}</div>: null}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM