2016-08-20 106 views
3

我知道,状态应该是一成不变的,这是一个没有没有,变异与按压状态下,在这个redux reducer中使用Object.assign的目的是什么?

//action = Object {type: "CREATE_COURSE", course: {title: algebra}} 

export default function courseReducer(state = [], action) { 
    switch(action.type) { 
     case 'CREATE_COURSE': 

      state.push(action.course) 
      return state; 

     default: 
      return state; 
    } 
} 

Pluralsight recommends this: 

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

     default: 
      return state; 
    } 
} 

但什么是错的没有使用object.assign?这有什么问题,似乎应用程序仍然有效。状态仍然没有发生变化,正在返回一个新的数组。

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

     default: 
      return state; 
    } 
} 

CourseActions:

export function createCourse(course) { 
    return { type: 'CREATE_COURSE', course}; 
} 

CoursesPage组件:

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

class CoursesPage extends React.Component { 
    constructor(props, context) { 
     super(props, context); 

     this.state = { 
      course: { title: '' } 
     }; 

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

    onTitleChange(event) { 
     const course = this.state.course; // assign this.state.course to course 
     course.title = event.target.value; // reassign course.title to whatever was in input 
     this.setState({course: course}); // reassign state course to new course object with updated title 
    } 

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

    courseRow(course, index) { 
     return <div key={index}>{course.title}</div>; 
    } 
    render() { 
     return (
       <div> 
        <h1>Courses</h1> 
        {this.props.courses.map(this.courseRow)} 
        <h2>Add Course</h2> 
        <input 
         type="text" 
         onChange={this.onTitleChange} 
         value={this.state.course.title} /> 
        <input 
         type="submit" 
         value="Save" 
         onClick={this.onClickSave} /> 
       </div> 
     ); 
    } 
} 

CoursesPage.propTypes = { 
    courses: PropTypes.array.isRequired, 
    actions: PropTypes.object.isRequired 
}; 

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

function mapDispatchToProps(dispatch) { 
    return { 
     actions: bindActionCreators(courseActions, dispatch) 
    }; 
} 

export default connect(mapStateToProps, mapDispatchToProps)(CoursesPage); 

回答

0

如果你不使用Object.assign,新数组的最后一个元素将是action.course参考,无论这是一个参考。传递引用可能会正常工作,但如果某处发生某种变化并导致问题 - 它们将很难调试。比对不起更安全。

0

,如果你只是把参考action.course阵列中,所有使用this.props.courses会看到所有的数组中的course物体的部件共享相同的参考,不应该达到的地步了一个问题,任何的组件有意/无意地甚至暂时地改变它们中的任何一个。

+0

我在尝试添加第二个课程时实际发生此错误: 未捕获的不变违规:在调度之间检测到状态变化,路径为“courses.0.title”。这可能导致不正确的行为。 我认为它是因为action.course直接引用组件中的相同状态,可以通过直接在输入中输入来突变,这就是为什么需要Object.assign。另外,尽管第一个课程被正确添加,但实际上双向输入会修改刚添加的课程,但这不应该发生。 我给OP增加了更多的背景代码。 – yxu296

相关问题