React setState
는 호출 될 때마다 모든 구성 요소 및 하위 구성 요소를 다시 렌더링합니까 ?
그렇다면 왜 그렇습니까? React는 상태가 변경 될 때 React가 필요한만큼만 렌더링한다는 생각을했습니다.
다음 간단한 예제에서 onClick 핸들러는 항상 state
같은 값으로 설정하므로 후속 클릭에서 상태가 변경되지 않더라도 텍스트를 클릭하면 두 클래스가 다시 렌더링됩니다 .
this.setState({'test':'me'});
state
데이터가 변경된 경우에만 렌더링이 발생할 것으로 예상했습니다 .
다음 은 JS Fiddle 및 포함 된 스 니펫 인 예제 코드입니다.
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
[1]: http://jsfiddle.net/fp2tncmb/2/
답변
React는 setState가 호출 될 때마다 모든 구성 요소 및 하위 구성 요소를 다시 렌더링합니까?
기본적으로-예.
이 방법이다 shouldComponentUpdate 부울 (개체 nextProps, 객체 nextState) , 각 구성 요소는이 방법을 가지고는 그것을 결정하는 책임이 “구성 요소 업데이트 (실행이되어야 렌더링 기능)?” 상태 를 변경 하거나 부모 구성 요소에서 새 소품 을 전달할 때마다 .
구성 요소에 대해 shouldComponentUpdate 메서드를 직접 구현할 수 있지만 기본 구현은 항상 true를 반환합니다. 즉, 항상 렌더링 함수를 다시 실행합니다.
공식 문서에서 인용 http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
기본적으로 shouldComponentUpdate는 상태가 변경 될 때 미묘한 버그를 방지하기 위해 항상 true를 반환하지만, 상태를 항상 변경할 수없는 것으로 취급하고 render ()의 props 및 state에서 읽기 전용으로주의해야하는 경우 shouldComponentUpdate를 기존 소품과 상태를 대체품과 비교하는 구현입니다.
질문의 다음 부분 :
그렇다면 왜 그렇습니까? 나는 아이디어가 상태가 변했을 때 React가 필요한만큼만 렌더링한다고 생각했습니다.
“렌더링”이라고하는 두 단계가 있습니다.
-
가상 DOM 렌더 : render 메소드가 호출 되면 컴포넌트 의 새로운 가상 dom 구조를 리턴합니다 . 앞에서 언급했듯이,이 렌더링 메소드는 setState () 를 호출 할 때 항상 호출 됩니다. shouldComponentUpdate 는 기본적으로 항상 true를 반환 하기 때문 입니다. 따라서 기본적으로 React에는 최적화가 없습니다.
-
Native DOM 렌더 : React는 Virtual DOM에서 변경된 경우에만 브라우저에서 실제 DOM 노드를 변경하고 필요한만큼만 변경합니다. 이는 실제 DOM 돌연변이를 최적화하고 React를 빠르게 만드는 뛰어난 React 기능입니다.
답변
아니요, React는 상태가 변경 될 때 모든 것을 렌더링하지 않습니다.
-
구성 요소가 더럽거나 (상태가 변경 될 때마다) 해당 구성 요소와 해당 하위 구성 요소가 다시 렌더링됩니다. 이것은 어느 정도까지 가능한 한 적게 다시 렌더링하는 것입니다. 렌더가 호출되지 않는 유일한 시점은 일부 브랜치를 다른 루트로 옮길 때입니다. 이론적으로 우리는 아무것도 다시 렌더링 할 필요가 없습니다. 귀하의 예에서는
TimeInChild
의 하위 구성 요소Main
이므로Main
변경 상태가되면 다시 렌더링됩니다 . -
반응은 상태 데이터를 비교하지 않습니다.
setState
호출 되면 구성 요소를 더티로 표시합니다 (즉, 다시 렌더링해야 함). 주목할 점은render
컴포넌트의 메소드가 호출되지만 실제 DOM은 출력이 현재 DOM 트리와 다른 경우에만 업데이트된다는 것입니다 (가상 DOM 트리와 문서의 DOM 트리 사이의 차이). 귀하의 예에서는state
데이터가 변경되지 않았 더라도 마지막 변경 시간이 변경되어 Virtual DOM이 문서의 DOM과 다르므로 HTML이 업데이트되는 이유가 있습니다.
답변
여기에 다른 많은 답변에 언급되어 있지만 구성 요소는 다음 중 하나 여야합니다.
-
shouldComponentUpdate
상태 또는 속성이 변경 될 때만 렌더링하도록 구현 -
얕은 비교를 위해 이미 내부적 으로 메소드를 구현 하는 PureComponent 확장으로 전환하십시오
shouldComponentUpdate
.
다음은 shouldComponentUpdate
간단한 사용 사례 및 데모 목적으로 만 작동하는를 사용하는 예제입니다 . 이것을 사용하면 구성 요소는 더 이상 클릭 할 때마다 다시 렌더링되지 않으며 처음 표시 될 때와 한 번 클릭 한 후에 렌더링됩니다.
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
shouldComponentUpdate: function(nextProps, nextState) {
if (this.state == null)
return true;
if (this.state.test == nextState.test)
return false;
return true;
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
답변
예. “shouldComponentUpdate”가 false를 반환 할 때 setState를 호출 할 때마다 render () 메소드를 호출합니다.
답변
“업데이트 손실”의 또 다른 이유는 다음과 같습니다.
- 정적 getDerivedStateFromProps 가 정의 된 경우 공식 문서 https://reactjs.org/docs/react-component.html#updating 에 따라 모든 업데이트 프로세스에서 다시 실행됩니다 .
- 따라서 상태 값이 처음에 props에서 나온 경우 모든 업데이트에서 덮어 씁니다.
그것이 문제라면 U는 업데이트하는 동안 상태를 설정하지 않아도되므로 상태 매개 변수 값을 다음과 같이 확인해야합니다
static getDerivedStateFromProps(props: TimeCorrectionProps, state: TimeCorrectionState): TimeCorrectionState {
return state ? state : {disable: false, timeCorrection: props.timeCorrection};
}
또 다른 해결책은 초기화 된 속성을 state에 추가하고 처음에 설정합니다 (상태가 null이 아닌 값으로 초기화 된 경우).
답변
모든 구성 요소가 아닙니다.
state
성분에 보이는 전체 APP 상태의 폭포 소스처럼.
따라서 setState가 호출 된 위치에서 변경이 발생합니다. renders
그때 의 나무가 거기에서 불러옵니다. 순수한 구성 요소를 사용한 경우 render
건너 뜁니다.