2017-05-18 1 views
1

나는 우리가 감속기에서 불변의 상태를 유지해야하는 이유를 궁금해. 이것이 필수인가 아니면 단순히 권장되는 접근인가? redux가 최적화를 수행하기 위해 변경할 수없는 것을 이용합니까?redux에서, 우리는 왜 감속기에서 상태를 불변으로 유지해야합니까?

몇 가지 실험 후, 나는 REDUX이 불변 일의 사용을 않는 것을 발견했습니다. 그 이유 중 하나는 감속기에서 주에 대해 동일한 참조를 반환 할 때 상태가 변경된 경우에도 UI가 업데이트되지 않아야한다는 것입니다. 아래의 예에서와 같이 :

const reducer = (state = [], action) => { 
 
\t switch(action.type) { 
 
\t \t case 'BRING_UP_NEXT_IMAGE': 
 
\t \t \t \t state.push(state.shift()); 
 
\t \t \t \t break; 
 
\t \t default: 
 
\t \t \t return state; 
 
\t } 
 
\t return state; 
 
};

돌아 오는이 (가 가치가 무엇인지에 대해) 동일한 상태의 참조를 감지하기 때문에 UI가 업데이트되지 않습니다.

우리가 UI를 업데이트 할 경우 우리가 국가에 새 참조를 반환해야 할 필요성을 설명합니다. 그러나 왜 Redux는 내부 상태 구조가 변경 불가능해야한다고 요구합니까? 내가 볼 수 있듯이 UI가 업데이트되는지 여부는 상태 참조 자체가 변경되었는지 여부에 따라 다릅니다. 나는 내부 구조를 변이하더라도 응용 프로그램에서와 같이,뿐만 아니라 정상적으로 작동합니다

const reducer = (state = [], action) => { 
 
\t switch(action.type) { 
 
\t \t case 'BRING_UP_NEXT_IMAGE': 
 
\t \t \t \t state = state.concat(state.shift()); 
 
\t \t \t \t break; 
 
\t \t default: 
 
\t \t \t return state; 
 
\t } 
 
\t return state; 
 
};

예, 이후 ") (state.shift"와 이전 상태를 변이, 그러나 않습니다 state.concat은 배열에 대한 새로운 참조를 반환합니다. 상태 자체는 다른 참조이며 앱은 정상적으로 작동합니다.

요컨대, 내가 알고 싶은 것은 국가가 엄격하게 불변으로 유지되어야하는지 여부는 Redux 기능을 올바르게 만들기위한 필요성이거나 shouldComponentUpdate에서 얕은 비교를 사용하여 앱이 더 나은 성능을 얻을 수 있도록 권장되는 옵션입니다. 화해 과정을 건너 뛸 수 있습니까?

답변

2

내 블로그 게시물 Idiomatic Redux: The Tao of Redux, Part 1 - Implementation and Intent 깊이에서이 문제를 논의 :

는 또한 그것을 설명하는 REDUX 문서의 부분이 있습니다.

핵심 돌아 오는 createStore 기능 자체가 당신이 당신의 코드를 작성해야하는에서만 두 가지 제한을두고 : 행동은 일반 객체이어야하며, 그들은 정의 type 필드를 포함해야합니다 요약 섹션을 인용. 불변성, 직렬화 가능성 또는 부작용, 또는 type 필드의 값이 실제로 무엇인지는 상관하지 않습니다.

반작용-돌아 오는이, 반작용, 돌아 오는 DevTools로 포함하는 코어 주위에 일반적으로 사용되는 조각 말했다, 그리고 다시 선택은 이 변하지, 직렬화 행동/상태의 적절한 사용, 순수한 감속기 기능을에 의존 할 . 이러한 기대를 무시하면 주 애플리케이션 로직이 정상적으로 작동하지만 시간 이동 디버깅 및 컴포넌트 재 렌더링이 중단 될 가능성이 큽니다. 이는 또한 다른 지속성 관련 유스 케이스에도 영향을 미친다.

불변, 직렬화 가능 및 순수 함수가 Redux에 의해 어떤 식 으로든 적용되지 않는다는 점에 유의해야합니다. 감속기 기능이 상태를 변경하거나 AJAX 호출을 트리거하는 것은 전적으로 가능합니다. 응용 프로그램의 다른 부분에서는 getState()을 호출하고 상태 트리의 내용을 직접 수정할 수 있습니다. 약속, 함수, 심볼, 클래스 인스턴스 또는 기타 비 직렬화 가능 값을 액션 또는 상태 트리에 넣을 수 있습니다. 당신은 이 그러한 것들을 수행하기 위해이라고 생각하지 않지만, 가능함은입니다.

Redux가 불변성에 의존하는 방법과 이유에 대한 세부 사항은 Immutable Data FAQ section의 Redux 문서에도 설명되어 있습니다.

0

반응 수명주기 방법 componentWillReceiveProps, shouldComponentUpdatecomponentWillUpdate 상태 nextProps를 변경하면 this.props는 동일합니다. 문제를 디버그하기가 어렵습니다. 당신이 구성 요소가 때 "제대로 REDUX 기능"매장의 변화에 ​​재 렌더링한다고 가정하면

2

그들은 다음 단지 기능이 제대로 당신이 당신의 국가의 새 복사본을 반환하는 경우 가입.

REDUX '연결 방법은 신원 확인을 포함 않는 기본 shouldComponentUpdate을 구현했습니다.

은 새로운 정체성을 작성하지 않고 직접 상태를 수정하는 경우, 당신은 단지 새로운 상태뿐만 아니라 기존의 상태를 변경하지 않을 매장에서 동일한 기준에 모두 포인트를 야기한다. 동일한 참조가 있으면 this.props.somePropFromStore === this.nextProps.somePropFromStore가 항상 true가됩니다. 이로 인해 사용자 정의 동작을 구현하지 않으면 redux가 더 이상 상태 변경을 감지하지 못하게됩니다.

나는 "권장 옵션"이상이라고 말합니다. 왜냐하면 redux의 기본 원칙 인 "절대 데이터를 변경하지 마십시오"를 사용하면 redux 저장소 엔진을 글로벌 저장소와 유사한 변수로 대체 할 수 있습니다 정보. http://redux.js.org/docs/faq/ReactRedux.html#why-isnt-my-component-re-rendering-or-my-mapstatetoprops-running

관련 문제