Reputation: 1415
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.
Upvotes: 1
Views: 941
Reputation: 282120
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}
Upvotes: 1
Reputation: 167
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);
Upvotes: 1
Reputation: 736
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.
Upvotes: 1