2016-08-20 108 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

相關問題