【问题标题】:Errors while Using map functions in React在 React 中使用地图函数时出错
【发布时间】:2017-02-04 04:12:37
【问题描述】:

我正在尝试使用地图功能显示一些数据,但我不断收到警告和错误。 他们是

警告:React 性能测量代码中存在内部错误。没想到 componentDidMount 计时器在另一个实例的渲染计时器仍在进行中时启动。

另一个是

未捕获的类型错误:无法读取未定义的属性“地图”

我发现 this.props.courses.map 返回 null 但我仍然不知道为什么?

import React,{PropTypes} from 'react';
import {connect} from 'react-redux';
import * as courseActions from '../actions/courseActions';


class CoursesPage extends React.Component{

    constructor(props,context){
       super(props,context);

       this.state={
         course:[{id:1,title:'hello'}]
       };

       this.onTitleChange = this.onTitleChange.bind(this);
       this.onClickSave = this.onClickSave.bind(this);

    }

    onTitleChange(event){
      const course = this.state.course;
      course.title = event.target.value;
      this.setState({course:course});
    }

    onClickSave(){
       this.props.dispatch(courseActions.createCourse(this.state.course));
    }

    courseRow(){
      return this.props.courses.map((course)=>{
          return(
            <div key={course.id}>{course.title}</div>
          );
      });
    }

    render(){
      return(
        <div>
          <h2>hello</h2>
          <h3>{this.courseRow()}</h3>
          <input type="text" onChange={this.onTitleChange} value={this.state.course.title}/>
          <input type="submit" value="save" onClick={this.onClickSave}/>
        </div>
      );
    }

}

CoursesPage.propTypes ={
   dispatch: PropTypes.func.isRequired,
   courses: PropTypes.array.isRequired
};

function mapStateToProps(state,ownProps){
     return{
        courses:state.courses
     };
}

export default connect(mapStateToProps)(CoursesPage);

这是我的减速器

export default function courseReducer(state = [],action){
    switch(action.type){
       case 'CREATE_USER':
         state.push(action.user);
          return [...state,Object.assign({},action.user)];
         default:
          return state;
      }
}

我的rootReducer

import {combineReducers} from 'redux';
import users from './userReducer';
import courses from './courseReducer';

const rootReducer = combineReducers({
  users:users,
  courses:courses
});

export default rootReducer;

商店

import {createStore,applyMiddleware} from 'redux';
import rootReducer from '../reducers/rootReducer';

export default function configureStore(initialState){
  return createStore(
     rootReducer,
     initialState
   );
}

【问题讨论】:

  • 你打错了 this.state.course 已定义但 "courses" 没有。
  • @JustinHerter 抱歉应该是 this.props.courses.map 但仍然出现同样的错误
  • ??? props.courses 不是数组,否则将定义 .map。 console.log("props: ",props) 在你的构造函数中看看有什么。
  • 你能分享你的 store/reducers 吗?正在读取存储的课程为空或未定义,因此您会收到此错误。发布相关代码真的会有所帮助
  • 顺便说一句,您不应该在case CREATE_USER 中使用state.push(action.user)。如果这样做,您将添加用户两次。

标签: javascript reactjs ecmascript-6 redux react-redux


【解决方案1】:

您的mapStateToProps 正在返回一个reducer,而不是您可以立即使用的实际props。它应该看起来像这样:

function mapStateToProps(state,ownProps){
     return{
        ...state.courses
     };
}

【讨论】:

    【解决方案2】:

    您的 Redux 商店的 courses 可能在开始时是 undefined,因此 this.props.courses 变为 undefined。尝试访问 .mapundefined 会给你上面提到的错误。有几种方法可以解决此问题:

    方法 1(推荐): 在 reducer 中将 state.courses 的初始值设置为空数组 []。请参阅有关 Reducers 的文档以了解如何设置初始状态:http://redux.js.org/docs/basics/Reducers.html

    方法2:mapStateToProps中为props.courses设置一个默认值。

    function mapStateToProps(state,ownProps){
      return {
        courses: state.courses || []
      };
    }
    

    方法3:在渲染之前检查this.props.courses不是undefinednull

    courseRow() {
      if (!this.props.courses) {
        return null;
      }
    
      return this.props.courses.map((course)=>{
        return(
          <div key={course.id}>{course.title}</div>
        );
      });
    }
    

    【讨论】:

      【解决方案3】:

      在你的减速器中你在哪里更新课程?我只能从您发布的代码中看到用户。

       const initialState = {
              courses : [],
       }
      
      
      
      export default function courseReducer(state =initialState,action){
          switch(action.type){
             //create a course or update it , else value is 
             //undefined and your map would throw error.
             case 'CREATE_COURSES':
               return Object.assign({},state,{
                       courses : action.user}
                );
               default:
                return state;
            }
      }
      

      此外,在您的渲染方法中,您需要检查此值是否已填充,然后仅运行地图。

       <h3>{this.props.courses.length > 1 ? this.courseRow() : null}</h3>
      

      【讨论】:

      • 恐怕这是不正确的。他的combineReducers 很好,users: users 只是users 的加长版本。其次,课程是一个数组,但您在 courseReducer 中返回一个对象。
      • 是的,我在这里返回状态对象。课程是状态对象中的一个数组,所以我想应该没问题。
      • @HarkiratSaluja 现在我收到一个错误,因为 Reducer“课程”在初始化期间返回未定义。如果传递给 reducer 的状态未定义,则必须显式返回初始状态。初始状态可能不是未定义的。
      • 你是否在你的 switch 语句中添加了默认值?
      • 如果this.props.coursesundefinedthis.props.courses.length &gt; 1 仍然会遇到同样的问题。 @TRomesh 请试试我的建议。
      【解决方案4】:

      在@Harkirat Saluja 和@Yang Shun 的帮助下修改了代码。我设法解决了初始化课程的问题,所以我改变了我的减速器,如下所示

      state = [] 成功了!

       export default function courseReducer(state = [],action){
              switch (action.type) {
                case 'CREATE_COURSE':
                      return [...state,Object.assign({},action.course)];
                 default:
                  return state;
      
              }
          }
      

      【讨论】:

      • 乐于帮助 :) 。你能接受答案吗?
      猜你喜欢
      • 2018-04-01
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      相关资源
      最近更新 更多