简体   繁体   中英

react-redux Reducer doesn't pass the object to the store

I have an issue and I could really use some help. I am very new to react and react-redux, so the solution is probably simpler than I might think(I hope so). I have a simple site, that contains Links (from react-router) with names of recipes:

class Posts extends Component {

    componentWillMount() {
        this.props.fetchPosts();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.newPost) {
            this.props.posts.unshift(nextProps.newPost);
        }
    }


    render() {
        const postItems = this.props.posts.map(recipe => (
            <div key={recipe.id}>
                <Link to={`/recipe/id/${recipe.id}`}>{recipe.name}</Link>
            </div>
        ));

        return (

            <Router>
            <div>
                <h1>Well yeah</h1>
                {postItems}
                <Route path={`/recipe/id/:recipeId`} component={Post}/>
            </div>
            </Router>
        );
    }
}
Posts.propTypes = {
    fetchPosts: PropTypes.func.isRequired,
    posts: PropTypes.array.isRequired,
    newPost: PropTypes.object,
};

const mapStateToProps = state => ({
    posts: state.posts.items,
    newPost: state.posts.item,
});

export default connect(mapStateToProps, {fetchPosts})(Posts);

Now, I also have a component Post, which is supposed to be a single recipe.

class Post extends Component {
    static propTypes = {};

    componentDidMount() {
        this.props.fetch();
    }

    render() {
        return (
            <div>Hello{this.props.recipe.name}</div>
        );
    }
}

Post.propTypes = {
    fetch: PropTypes.func.isRequired,
    recipe: PropTypes.object
};

const mapDispatchToProps = (dispatch, ownProps) => ({
    fetch: () => {
        dispatch(fetchPostById(ownProps.location.pathname))
    }
});
const mapStateToProps = state => ({

    recipe: state.posts.recipe
});
export default connect(mapStateToProps, mapDispatchToProps)(Post);

Regardless of what I do, I can't seem to make it work properly. I have an action that fetches the single recipe(I have no problem fetching the list of recipes) and then pass it to the reducer. However, when I put console.log(action.payload) in the case in the reducer, it shows the Object containing the recipe in the console just fine. But when I put {this.props.recipe.name} in Post.js I get an error That this.props.recipe is undefined. Any help is very appreciated. To be sure, I will also post the code of the reducer and the actions.

Reducer:

const initialState = {
    items: [],
    item: {},
    recipe:{}

};

export default function (state = initialState, action) {
    switch (action.type) {
        case FETCH_RECIPES:
            return {
                ...state,
                items: action.payload
            };
        case NEW_RECIPE:
            return {
                ...state,
                item: action.payload
            };
        case FETCH_RECIPE_ID:
            return{
                ...state,
                recipe:action.payload
            };
        default:
            return state;
    }

}

Actions:

export const fetchPosts = () => dispatch => {
    fetch('http://192.168.1.3:6996/recipe')
        .then(res => res.json())
        .then(recipes => dispatch({
            type: FETCH_RECIPES,
            payload: recipes
        }));

};
export const createPost = (postData) => dispatch => {
    fetch('http://192.168.1.3:6996/recipe', {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify(postData)
    }).then(res => res.json()).then(recipe => dispatch({
        type: NEW_RECIPE,
        payload: recipe
    }))

};
export const fetchPostById= (id) => dispatch => {
    fetch('http://192.168.1.3:6996' + id)
        .then(recipe => recipe.json())
        .then(recipe => dispatch({
        type: FETCH_RECIPE_ID,
        payload: recipe
    }))
};

Main reducer:

import { combineReducers } from 'redux'
import postReducer from './postReducer'

export default combineReducers({
    posts: postReducer
});

after switching off WebStorm for the night, the site fired up the next morning and worked somewhat fine. I have a problem with the react-router part sill, but I will post different question, so I don't break any rules. Thanks a lot!

In this line recipe: state.posts.recipe you are implying that there is a posts object in your state that holds your recipe, but in the reducer, I don't see any posts object in your state. try changing it to this line recipe: state.recipe

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