전 이적으로 도달 할 수있는 모든 상태를 포함하는 반응 구성 요소를 어떻게 재설정 할 수 있습니까?


93

나는 때때로 내가 재설정하고 싶은 개념적으로 상태 저장되는 반응 구성 요소를 가지고 있습니다. 이상적인 동작은 이전 구성 요소를 제거하고 새롭고 깨끗한 구성 요소를 읽는 것과 같습니다.

React는 setState컴포넌트 자체의 명시 적 상태를 설정할 수 있는 방법 을 제공 하지만 브라우저 포커스 및 양식 상태와 같은 암시 적 상태를 제외하고 자식의 상태도 제외합니다. 모든 간접적 상태를 포착하는 것은 까다로운 작업 일 수 있으며, 모든 새로운 놀라운 상태를 가지고 두더지를 치는 것보다 엄격하고 완전하게 해결하는 것이 좋습니다.

이를위한 API 또는 패턴이 있습니까?

편집 : 나는 사소한 예제 시연했다 this.replaceState(this.getInitialState())접근을하고 그것을 대조 this.setState(this.getInitialState())방법 : jsfiddle을 - replaceState더 강력하다.

답변:


206

언급 한 암시 적 브라우저 상태와 자식 상태가 재설정 되도록하려면 ;에서 반환 한 루트 수준 구성 요소에 key속성 을 추가 할 수 있습니다 render. 변경되면 해당 구성 요소는 버려지고 처음부터 생성됩니다.

render: function() {
    // ...
    return <div key={uniqueId}>
        {children}
    </div>;
}

개별 구성 요소의 로컬 상태를 재설정하는 바로 가기는 없습니다.


1
'컴포넌트가 버려지고 처음부터 생성 될 것입니다'라고 말할 때 호기심으로 가상 DOM이 폐기되고 처음부터 생성되지만 DOM 업데이트는 여전히 diff 알고리즘을 기반으로 발생한다는 의미입니까?
nimgrg 2014

1
@nimgrg 아니요, 실제 DOM 요소도 다시 생성됩니다. (가상 DOM은 모든 렌더링에서 이미 재생성되어 있으므로 실제 DOM을 유지하려면 key이 경우 a 를 설정하지 마십시오 .)
Sophie Alpert

3
@EamonNerbonne React 0.8에서 키는 배열의 형제 요소를 구별하는 데만 사용되며 루트에서 무시되었습니다. github.com/facebook/react/issues/590을 참조 하세요 .
Sophie Alpert

replaceState()getInitialState()모두 새로운 ES6 클래스 스타일 reactjs에 사용되지 않습니다. this.setState(this._getInitialState())대신 사용하십시오 . 또한 자신의 상태 이니셜 라이저 함수의 이름을 지정할 수 없습니다. getInitialState()반응은 경고를 던집니다. 다른 이름을 호출 state = this._getInitialState()하고 클래스의 최상위 수준에서 명시 적으로 수행 합니다.
thom_nic

2
외부가 키 소품을 전달하지 않고도 구성 요소 내부에서이 작업을 수행 할 수있는 방법이 있습니까?
trusktr

14

실제로 피하고 대신 replaceState사용해야 setState합니다.

문서에는 replaceState"React의 향후 버전에서 완전히 제거 될 수 있습니다."라고되어 있습니다. replaceStateReact의 철학에 맞지 않기 때문에 확실히 제거 될 것이라고 생각합니다 . React 구성 요소가 스위스 칼처럼 느껴지기 시작하도록 도와줍니다. 이것은 React 구성 요소가 점점 작아지고 목적에 맞게 자연스럽게 성장하는 것을 방해합니다.

React에서 일반화 또는 전문화에 오류가있는 경우 : 전문화를 목표로합니다. 추론 적으로 구성 요소의 상태 트리에는 특정 간결함이 있어야합니다 (브랜드를 휩쓸고있는 신제품을 비계하는 경우이 규칙을 세련되게 위반하는 것이 좋습니다).

어쨌든 이것이 당신이하는 방법입니다. 위의 Ben의 (허용되는) 답변과 유사하지만 다음과 같습니다.

this.setState(this.getInitialState());

또한 (Ben도 말했듯이) "브라우저 상태"를 재설정하려면 해당 DOM 노드를 제거해야합니다. vdom의 힘을 활용하고 key해당 구성 요소에 대한 새로운 소품을 사용하십시오 . 새 렌더링은 해당 구성 요소 도매를 대체합니다.

참조 : https://facebook.github.io/react/docs/component-api.html#replacestate


2
현재 상태에 초기 상태가 아닌 속성이 포함되어 있으면 작동하지 않습니다. 나는 그것이 있어야 할 중대한 "상태"라고 생각하지 않지만, 어떻게 든 그것을 막을 수 없다면, 나는 놀라운 파손을 피하고 싶습니다. 경우에 따라 충돌 하는 재설정은 괜찮지 만 상태를 미묘하게 손상시키는 재설정은 아닙니다.
Eamon Nerbonne

내가 따르는 지 모르겠다. 이것이와 동등하지 않다는 this.replaceState말입니까? 그러니까.
wle8300

1
@ williamle8300 호출 사이의 구성 요소 수명주기 어딘가 getInitialState()(예 : onClick 처리기에서) 상태에 새 속성이 추가되는 경우에는 동일하지 않습니다 . 이 경우 새 속성은 2nd 이후에도 여전히 존재합니다 getInitialState().
Graham

@Graham 이미 선언되지 않은 구성 요소에 새 상태를 도입하는 것은 나쁜 습관이라고 생각합니다 getInitialState. 함수의 맨 위에있는 JS 함수에서 모든 변수를 선언하는 것과 비슷합니다. 참고 : Ben Alpert의 솔루션은 저와 거의 동일하며 공식 React 관리자입니다!
wle8300

1
getInitialState () 함수, 따라서 대답이 더 이상 사용되지 않는 것이 두렵습니다. 업데이트가 좋을 것입니다.
Martin R.

8

key다시 초기화해야하는 요소에 속성을 추가 하면 props또는 state요소가 변경 될 때마다 속성이 다시로드됩니다 .

key = {new Date (). getTime ()}

다음은 예입니다.

render() {
  const items = (this.props.resources) || [];
  const totalNumberOfItems = (this.props.resources.noOfItems) || 0;

  return (
    <div className="items-container">
      <PaginationContainer
        key={new Date().getTime()}
        totalNumberOfItems={totalNumberOfItems}
        items={items}
        onPageChange={this.onPageChange}
      />
    </div>
  );
}

1
또는 당신은 키와 같은 간단한 정수 카운터 변수를 추가 할 수 있습니다
미니멀
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.