简体   繁体   English

React-Redux:映射对象数组并初始化每个对象的组件

[英]React-Redux: mapping an array of objects and initializing a component from each

I have a presentational component, , which takes a {props} object and populates itself with the proper values. 我有一个演示组件,它带有一个{props}对象,并使用适当的值填充自身。

I also have a container component, , which is supposed to map state to props, take the array of objects representing the plots, map it and initialize a from each one. 我还有一个容器组件,应该将状态映射到道具,获取代表绘图的对象数组,将其映射并初始化每个对象。

This is throwing me an error- Uncaught (in promise) TypeError: Cannot read property 'name' of undefined . 这给我抛出一个错误- Uncaught (in promise) TypeError: Cannot read property 'name' of undefined The "name" in question is a property of the plot. 有问题的“名称”是情节的属性。

Looking at the documentation, this error typically happens when we import a component with curly braces when we should import it without, but that's not the case here. 查看文档,此错误通常发生在我们导入带有花括号的组件时,我们不应该导入它,而在这里不是这种情况。

I have a feeling that what is going on is that I am improperly passing the props to the element, but am not sure of the right way to do it. 我感觉发生了什么事,就是我没有正确地将道具传递给元素,但是不确定这样做的正确方法。

Plot.js: Plot.js:

import React from 'react';

const Plot = ({ props }) => {
    return (
        <div className="media col-md-4">
            <div className="media-left">
                <a href="#">
                    <img className="media-object" src="http://placehold.it/200/550" alt="Placehold" />
                </a>
            </div>
            <div className="media-body">
                <h4 className="media-heading">{props.name}</h4>
                <ul>
                    <li><strong>Grower: </strong> {props.grower}</li>
                    <li><strong>Region: </strong> {props.region}</li>
                    <li><strong>Current State: </strong> {props.currentState}</li>
                    <li><strong>Next State: </strong> {props.nextState}</li>
                    <li><strong>Days To Next State: </strong> {props.daysToNext}</li>
                    <br />
                    <span class="pull-right">
                        <i id="like1" class="glyphicon glyphicon-thumbs-up"></i> <div id="like1-bs3"></div>
                        <i id="dislike1" class="glyphicon glyphicon-thumbs-down"></i> <div id="dislike1-bs3"></div>
                    </span>
                </ul>
            </div>
        </div>
    );
};

export default Plot;

Dashboard.js: Dashboard.js:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Plot from './plot';

class Dashboard extends Component {
    componentWillMount() {
        this.props.fetchMessage();
        this.props.fetchPlots();
    }

    render() {
        const plots = this.props.plots;
        return (
            <div>
                <span>{this.props.message}</span>
                <div className='container'>
                        <div className="row">
                            {plots && plots.map((plot) => <Plot key={plot._id} name={plot.name} grower={plot.grower} region={plot.region} currentState={plot.currentState} nextState={plot.nextState} daysToNext={plot.daysToNext}/>)}
                        </div>
                </div>
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        message: state.auth.message,
        plots: state.auth.plots
    }
}

export default connect(mapStateToProps, actions)(Dashboard);

EDIT: 编辑:

This is fetchPlots(). 这是fetchPlots()。 I know that it's working and that plots are available as props, because when I add a console.(log) statement before the return statement in dashboard.js, I can see them, and they're fine, with all necessary properties. 我知道它可以正常工作,并且绘图可以用作道具,因为当我在dashboard.js中的return语句之前添加console。(log)语句时,我可以看到它们,并且它们具有所有必要的属性。

export function fetchPlots() {
    return function (dispatch) {
        axios.get(`${ROOT_URL}/plots`, {
            headers: {
                authorization: localStorage.getItem('token')
            }
        })
            .then(response => {
                dispatch({
                    type: FETCH_PLOTS,
                    payload: response.data
                });
            });
    }
}

My reducer: 我的减速器:

import {AUTH_USER, UNAUTH_USER, AUTH_ERROR, FETCH_MESSAGE, FETCH_PLOTS} from '../actions/types';

export default function(state={}, action){
    switch(action.type){
        case AUTH_USER:
            return{...state, error:'',authenticated:true};
        case UNAUTH_USER:
            return{...state, authenticated:false};
        case AUTH_ERROR:
            return { ...state, error: action.payload };
        case FETCH_MESSAGE:
            return { ...state, message: action.payload }
        case FETCH_PLOTS:
            return { ...state, plots: action.payload }
    }
    return state;

const Plot = ({ props })更改为const Plot = (props)

You are making an ajax call to get the data. 您正在进行ajax调用以获取数据。 So the ajax call takes some time to execute. 因此,ajax调用需要一些时间来执行。 Because of which this.props.plots would be undefined. 因此, this.props.plots是不确定的。 So you need to make a null check in your Dashboard component 因此,您需要在Dashboard组件中进行空检查

render() {
    const plots = this.props.plots;
    if(plots === undefined){
        return <div>Loading ...</div>
    }
    return (
        <div>
            <span>{this.props.message}</span>
            <div className='container'>
                    <div className="row">
                        {plots && plots.map((plot) => <Plot key={plot._id} name={plot.name} grower={plot.grower} region={plot.region} currentState={plot.currentState} nextState={plot.nextState} daysToNext={plot.daysToNext}/>)}
                    </div>
            </div>
        </div>
    );
}

Once the ajax call is finished the render function will be called again then the else condition will be followed and then it will not give the error you are getting. 一旦ajax调用完成,将再次调用render函数,然后将遵循else条件,然后它不会给出您遇到的错误。

Also make your api calls from componentDidMount() so that it's not called every time the state changes. 还要从componentDidMount()进行api调用,以便每次状态更改时都不会调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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