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

당신이 action.course에 대한 참조가 될 것입니다 Object.assign, 새로운 배열의 마지막 요소를 사용하지 않는 경우와 그것이 무엇이든간에. 참조를 전달하면 정상적으로 작동하지만 문제가 발생하면 디버깅하기가 어려울 수 있습니다. 죄송합니다보다 더 안전.

0

그냥 배열에 action.course에 대한 참조를 넣어 경우, this.props.courses 배열의 모든 course 객체를 볼 수 있습니다 사용하는 모든 구성 요소는 지금까지 문제가되지해야 동일한 참조를 공유하고있는 모든 구성 요소의 의도적/비 의도적으로 일시적인 경우에도 이들 중 하나를 변경합니다.

+0

두 번째 코스를 추가하려고 할 때 실제로이 오류가 발생합니다. 잡히지 않는 불변 위반 : 'courses.0.title' 경로에서 파견간에 상태 변경이 감지되었습니다. 이로 인해 잘못된 동작이 발생할 수 있습니다. action.course는 직접 입력에 입력하여 변형 될 수있는 구성 요소의 동일한 상태를 직접 참조하므로 Object.assign이 필요한 이유입니다. 또한 첫 번째 코스가 올바르게 추가되었지만 입력 내용을 실제로 양방향으로 입력하면 방금 추가 한 코스가 수정되어서 발생하지 않아야합니다. OP에 배경 코드를 추가했습니다. – yxu296

관련 문제