首页 > 解决方案 > 在 react+redux 应用的 Home 组件中,在 componentdidmount 上调用 action getPosts() 后 this.props.posts 未定义

问题描述

我正在尝试制作一个博客风格的应用程序。我正在运行一个 django 服务器并尝试制作一个 react-redux 前端。我正在使用 redux-devtools,当我注释掉错误代码时,redux 似乎有数据在状态。不知道出了什么问题。另外,我正在使用 redux-thunk 和 axios 与后端进行通信。我几乎是从 youtube 教程中复制的。这是reducer reducers/posts.js


    import {GET_POSTS} from "../actions/types";

    const initialState = {
        posts: []
    }

    export default function(state = initialState, action) {
        switch (action.type) {
            case GET_POSTS:
                return {
                    ...state,
                posts: action.payload
            }
            default:
                return state;
        }
    }

这是动作actions/posts.js


    import axios from "axios";
    import {GET_POSTS} from "./types";

    export const getPosts = () => dispatch => {
        axios.get('/get/posts/').then(res => {
            dispatch({
                type: GET_POSTS,
                payload: res.data
            })
        }).catch(error => {console.log(error)})
    }

这是reducers/index.js


    import {combineReducers} from 'redux';
    import posts from "./posts";
    export default combineReducers({
        posts
    });

这是 store.js


    import {createStore, applyMiddleware} from 'redux';
    import {composeWithDevTools} from 'redux-devtools-extension';
    import thunk from 'redux-thunk';
    import rootReducer from './reducers';

    const initialState = {};

    const middleware = [thunk];

    const store = createStore(
        rootReducer,
        initialState,
        composeWithDevTools(applyMiddleware(...middleware))
    );
    export default store;

这是组件/Home.js(此处错误)


    import React from 'react';
    import {connect} from 'react-redux';
    import {getPosts} from '../actions/posts';
    class Home extends React.Component {
        componentDidMount() {
            this.props.getPosts();
        }
        render() {
            console.log(this.props.posts); //undefined
            const posts = this.props.posts.map(post => (
                <div className="post">
                    <h1>{post.title}</h1>
                    <p>{post.message}</p>
                </div>
                )
            )
            return (
                {posts}
            )
        }
    }
    const mapStateToProps = state => ({
        posts: state.posts // I have tried state.posts
    // and state.posts.posts. I think 
    //state.posts might be undefined which is 
    //causing this.props.posts to be undefined in the component
    });
    export default connect(mapStateToProps, {getPosts})(Home);

回答:我发现render被多次调用,第一次调用时,this.props.posts是未定义的,所以我为this.props.posts是否未定义添加了一个if语句,如果不是,我渲染名单。

标签: javascriptdjangoreactjsreduxreact-redux

解决方案


在您返回内部Home组件时,请执行以下操作:

return (
        {this.posts.length > 0 && posts}
)

您的初始渲染正在尝试渲染尚未从服务器获取的元素数组。所有对 web apis 和后端服务器的 fetch 调用都是异步的,这意味着它们将在 JS 引擎的堆栈帧空闲时立即执行。添加条件语句将允许您做一个额外的事情,check这将重新呈现页面,因为数据将被提取并存储到您的减速器。此外,当不确定您的 redux 存储的状态/形状时,您始终可以像这样在控制台记录它:

const mapStateToProps = state => {
 console.log(state);
 return {
  posts: state.posts
 }
}

推荐阅读