0

I am new to React-Redux and I have a problem with redux action object. When I am printing the object to the console, it displays correctly as shown below: shown below

Please check my codes.

FeedPage.jsx

class FeedPage extends React.Component {
    componentDidMount() {
        const { id } = this.props.match.params;
        this.props.dispatch(feedActions.getById(id));
        console.log("props", this.props);
    }

    render() {
        const { user, feed } = this.props;

    ... 

function mapStateToProps(state) {
    const { feed, authentication } = state;
    const { user } = authentication;
    console.log(JSON.stringify(feed));
    return {
        user,
        feed
    };
}

const connectedFeedPage = connect(mapStateToProps)(FeedPage);
export { connectedFeedPage as FeedPage };   

reducer.js

export function feeds(state = {}, action) {
switch (action.type) {
    case feedConstants.GETBYID_REQUEST:
    return {
        loading: true
    };
    case feedConstants.GETBYID_SUCCESS:
    console.log("GETBYID_SUCCESS: " + JSON.stringify(action.feed));
    return {
        feed: action.feed
    };
    case feedConstants.GETBYID_FAILURE:
    return { 
        error: action.error
    };

    ...

service.js

function getById(id) {
    const requestOptions = {
        method: 'GET',
        headers: authHeader()
    };

    return fetch(`${config.apiUrl}/feed/${id}`, requestOptions).then(handleResponse);
}   

actions.js

function getById(id) {
    return dispatch => {
        dispatch(request());

        feedService.getById(id)
            .then(
                feed => dispatch(success(feed)),
                error => dispatch(failure(error.toString()))
            );
    };

    function request() { return { type: feedConstants.GETBYID_REQUEST } }
    function success(feed) { return { type: feedConstants.GETBYID_SUCCESS, feed } }
    function failure(error) { return { type: feedConstants.GETBYID_FAILURE, error } }
}

UPDATE:

root reducer

import { combineReducers } from 'redux';

import { authentication } from './authentication.reducer';
import { registration } from './registration.reducer';
import { users } from './users.reducer';
import { alert } from './alert.reducer';
import { feeds } from './feeds.reducer';

const rootReducer = combineReducers({
    authentication,
    registration,
    users,
    alert,
    feeds
});

export default rootReducer;

This is the screenshot of the logs:

logs

So it is clear that feed object is not empty. But when I am referencing it, it is undefined. Please help as I am stuck and cannot move forward. Any help is great appreciated. Thank you!

4
  • please show your root reducer, I think I know what the problem might be... Commented Aug 24, 2018 at 21:17
  • @ChrisCousins posting now. Please check. Commented Aug 24, 2018 at 21:21
  • 1
    you're talking about referencing it in render method ? right Commented Aug 24, 2018 at 21:24
  • @SakhiMansoor yep you're right. Commented Aug 24, 2018 at 21:28

2 Answers 2

2

In your root reducer, you are saying that the item "feeds" will contain what your feedReducer gives it. In your feedReducer you return "feed: action.feed".

So, in your mapStateToProps, you should be mapping "feeds", not "feed". When you then read the feeds value, it will contain an object such as { feed: xxx } where xxx is what your action originally had in it after your API call.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for bringing this to my attention. However, I cannot access the property of feed. I tried doing this: feeds.feed.id but it's undefined.
What do you get when you console.log(feeds)? Also, please update the code in the question to reflect any changes to mapStateToProps etc.
{"feed":{"id":5,"description":"Latest update 5","created_by":{"id":10002,"first_name":"James","last_name":"Estrada"},"date_created":"2018-08-14T02:16:17.961Z","date_modified":"2018-08-14T02:16:17.961Z","modified_by":null}}
In your render function, it is entirely possible that your async feeds data hasn't arrived yet. Make sure in your render function, you check whether feeds has anything in it (for instance if(feeds.feed) { ... }) and if it doesn't, just return null from the render function.
yey that works! Thank you. Tried something like this: { feeds.feed ? feeds.feed.id : '' }
|
0

There's an issue with your reducer. You're mutating component state as it store doesn't get updated when we mutate the state and component doesn't re render

case feedConstants.GETBYID_SUCCESS:
    console.log("GETBYID_SUCCESS: " + JSON.stringify(action.feed));
    return {
      ...state,
      feed: action.feed
    };

in your case Redux doesn't detect a difference in state and won't notify your components that the store has changed and you should return a new copy of state with the necessary change. Hope this would solve the issue Let me know if the issue still persists.

1 Comment

and you can get updated state in componentWillReceiveProps() and you can setState there and your component will re render.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.