Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 警告:失败的道具类型:道具'exercise'在'EditExercise'中标记为必需,但其值为'undefined'`_Javascript_Reactjs - Fatal编程技术网

Javascript 警告:失败的道具类型:道具'exercise'在'EditExercise'中标记为必需,但其值为'undefined'`

Javascript 警告:失败的道具类型:道具'exercise'在'EditExercise'中标记为必需,但其值为'undefined'`,javascript,reactjs,Javascript,Reactjs,我正在尝试从MongoDB获取一个对象。我成功地得到了整个数据库。 当我在console.log()中读取reducer中的有效负载时,它显示的是单个对象而不是数组,以及我想要的正确对象。 我无法理解为什么不将对象发送到组件,因为我在不同的组件中执行完全相同的过程 从操作文件:exerciseActions.js: export const getExerciseByID = (exerciseID) => dispatch => { fetch('http://localh

我正在尝试从MongoDB获取一个对象。我成功地得到了整个数据库。 当我在console.log()中读取reducer中的有效负载时,它显示的是单个对象而不是数组,以及我想要的正确对象。 我无法理解为什么不将对象发送到组件,因为我在不同的组件中执行完全相同的过程

从操作文件:exerciseActions.js:

export const getExerciseByID = (exerciseID) => dispatch => {
    fetch('http://localhost:5000/exercises/' + exerciseID)
        .then(res => res.json())
        .then(exercise => dispatch({
            type: GET_BY_ID,
            payload: exercise
        }))
}
减速器:

   import { FETCH_EXERCISES, NEW_EXERCISE, EXERCISE_REMOVE, GET_BY_ID } from '../actions/types'

const initialState = {
    exercises: [],
    exercise: {}
}

export default function (state = initialState, action) {
    switch (action.type) {
        case FETCH_EXERCISES:
            return {
                ...state,
                exercises: action.payload
            };
        case NEW_EXERCISE:
            return {
                ...state,
                exercise: action.payload
            };
        case EXERCISE_REMOVE:
            return {
                ...state,
                exercises: state.exercises.filter(exercises => exercises._id !== action.exercises._Id)
            };
        case GET_BY_ID:
            console.log(action.payload);
            return {
                exercise: action.payload
            }

        default: return state;
    }

}
反应组分:

import React, { Component } from 'react';
import axios from 'axios';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { getExerciseByID } from '../actions/exerciseActions'

class EditExercise extends Component {
    constructor(props) {
        super(props);

        this.onChangeUsername = this.onChangeUsername.bind(this);
        this.onChangeDescription = this.onChangeDescription.bind(this);
        this.onChangeDuration = this.onChangeDuration.bind(this);
        this.onChangeDate = this.onChangeDate.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            exercise: null,
            users: []
        }
    }
    componentWillMount() {
        const exercise = this.props.getExerciseByID(this.props.match.params.id);
        console.log(exercise);
    }

    render() {

        const exercise = this.props.exercise

        return (
            <div>
                <p>{exercise}
                </p>
                <h3>Edit Exercise Log</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group">
                        <label>Username: </label>
                        <select ref="userInput"
                            required
                            className="form-control"
                            value={this.state.username}
                            onChange={this.onChangeUsername}>
                            {
                                this.state.users.map(function (user) {
                                    return <option
                                        key={user}
                                        value={user}>{user}
                                    </option>;
                                })
                            }
                        </select>
                    </div>
                    <div className="form-group">
                        <label>Description: </label>
                        <input type="text"
                            required
                            className="form-control"
                            value={this.state.description}
                            onChange={this.onChangeDescription}
                        />
                    </div>
                    <div className="form-group">
                        <label>Duration (in minutes): </label>
                        <input
                            type="text"
                            className="form-control"
                            value={this.state.duration}
                            onChange={this.onChangeDuration}
                        />
                    </div>
                    <div className="form-group">
                        <label>Date: </label>
                        <div>
                            <DatePicker
                                selected={this.state.date}
                                onChange={this.onChangeDate}
                            />
                        </div>
                    </div>

                    <div className="form-group">
                        <input type="submit" value="Edit Exercise Log" className="btn btn-primary" />
                    </div>
                </form>
            </div>
        )
    }
}

EditExercise.propTypes = {
    getExerciseByID: PropTypes.func.isRequired,
    exercise: PropTypes.array.isRequired,
}

const mapStateToProps = state => ({
    exercise: state.exercise,
})

export default connect(mapStateToProps, { getExerciseByID })(EditExercise);
import React,{Component}来自'React';
从“axios”导入axios;
从“react DatePicker”导入日期选择器;
导入“react datepicker/dist/react datepicker.css”;
从“道具类型”导入道具类型
从“react redux”导入{connect}
从“../actions/exerciseActions”导入{getExerciseByID}
类扩展组件{
建造师(道具){
超级(道具);
this.onChangeUsername=this.onChangeUsername.bind(this);
this.onchangescription=this.onchangescription.bind(this);
this.onChangeDuration=this.onChangeDuration.bind(this);
this.onChangeDate=this.onChangeDate.bind(this);
this.onSubmit=this.onSubmit.bind(this);
此.state={
练习:空,
用户:[]
}
}
组件willmount(){
const exercise=this.props.getExerciseByID(this.props.match.params.id);
控制台日志(练习);
}
render(){
const exercise=this.props.exercise
返回(
{练习}

编辑练习日志 用户名: { this.state.users.map(函数(用户){ 返回{user} ; }) } 说明: 持续时间(分钟): 日期: ) } } EditExecution.propTypes={ getExerciseByID:PropTypes.func.isRequired, 练习:需要PropTypes.array.isRequired, } 常量mapStateToProps=状态=>({ 演习:国家演习, }) 导出默认连接(mapStateToProps,{getExerciseByID})(EditExercise);
您可能会找到原因。您应该使用componentDidMount

在componentWillMount()中使用fetch调用会导致组件首先呈现空数据,因为componentWillMount()在组件第一次呈现之前不会返回

由于JavaScript事件是异步的,因此当您进行API调用时,浏览器会在调用仍在运行时继续执行其他工作。使用React,组件渲染时不会等待componentWillMount()完成,因此组件将继续渲染


感谢您的输入,从现在起我将使用componentDidMount。但它并没有解决可能找不到锻炼的错误。您可能会忘记减速器的名称。const-mapStateToProps=state=>({exercise:state.exercise,//它应该是state。[reducerName].exercise})
case GET_BY_ID:
    console.log(action.payload);
    return {
        ...state, // Btw, you forgot this line
        exercise: action.payload
    }