구성 요소의 목적 / 크기 / 소품 / 동작에 따라이 세 가지 중에서 어떻게 결정합니까?
사용자 지정 방법으로 확장 React.PureComponent
하거나 확장하면 성능에 영향을 미칩니다. 상태 비 저장 기능 구성 요소를 사용하는 것은 "아키텍처"선택이며 아직 성능상의 이점이 없습니다.React.Component
shouldComponentUpdate
쉽게 재사용해야하는 간단한 프리젠 테이션 전용 구성 요소의 경우 상태 비 저장 기능 구성 요소를 선호합니다. 이렇게하면 실제 앱 로직에서 분리되어 테스트하기가 쉽고, 예상치 못한 부작용이 없는지 확인할 수 있습니다. 어떤 이유로 든 많은 이유가 있거나 렌더링 방법을 최적화 해야하는 경우 ( shouldComponentUpdate
상태 비 저장 기능 구성 요소를 정의 할 수 없기 때문에)는 예외입니다 .
확장 PureComponent
당신이 당신의 출력은 간단한 소품에 의존 알고있는 경우 / 상태 ( "간단한"얕은가 PureComponent의 수행으로, 중첩 된 데이터 구조를 비교 의미가없는) 당신이 필요 / 약간의 성능 향상을 얻을 수 있습니다.
다음 / 현재 소품과 상태간에 사용자 지정 비교 논리를 수행하여 성능 향상이 필요한 경우 Component
직접 확장 하고 구현하십시오 shouldComponentUpdate
. 예를 들어 lodash # isEqual을 사용하여 빠른 비교를 신속하게 수행 할 수 있습니다.
class MyComponent extends Component {
shouldComponentUpdate (nextProps, nextState) {
return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
}
}
또한 자체 구현 shouldComponentUpdate
또는 확장 PureComponent
은 최적화이며 평소와 같이 성능 문제가있는 경우에만 조사를 시작해야합니다 ( 조기 최적화를 피하십시오 ). 경험상 필자는 대부분의 기능이 이미 구현 된 상태에서 응용 프로그램이 작동 상태 인 후에 항상 이러한 최적화를 수행하려고합니다. 실제로 문제가 발생했을 때 성능 문제에 집중하는 것이 훨씬 쉽습니다.
자세한 내용은
기능적인 상태 비 저장 구성 요소 :
이것들은 단지 함수를 사용하여 정의됩니다. 상태 비 저장 구성 요소의 내부 상태가 없으므로 출력 (렌더링 된 내용)은이 함수에 입력으로 지정된 소품에만 의존합니다.
장점 :
React에서 컴포넌트를 정의하는 가장 간단한 방법. 상태를 관리 할 필요가 없다면 왜 클래스와 상속을 방해합니까? 함수와 클래스의 주요 차이점 중 하나는 함수를 사용하면 출력이 입력에만 의존한다는 것입니다 (이전 실행 기록이 아님).
앱에서 이상적인 상태 비 저장 구성 요소를 최대한 많이 확보하는 것이 이상적입니다. 일반적으로 뷰 레이어 외부에서 로직을 이동하고이를 redux와 같은 것으로 이동했기 때문에 아무것도 렌더링하지 않고도 실제 로직을 테스트 할 수 있습니다. (테스트하기가 쉽고, 재사용이 가능합니다.)
단점 :
수명주기 방법이 없습니다. componentDidMount
다른 친구 를 정의 할 수있는 방법이 없습니다 . 일반적으로 계층 구조에서 상위 구성 요소 내에서이를 수행하므로 모든 하위 항목을 상태 비 저장 구성 요소로 바꿀 수 있습니다.
을 정의 할 수 없으므로 다시 렌더링이 필요한시기를 수동으로 제어 할 수있는 방법이 없습니다 shouldComponentUpdate
. 다시 렌더링은 구성 요소가 새 소품을받을 때마다 발생합니다 (얕은 비교 등). 앞으로 React는 상태 비 저장 구성 요소를 자동으로 최적화 할 수있게되었으므로 현재 사용할 수있는 라이브러리가 몇 가지 있습니다. 상태 비 저장 구성 요소는 단순한 기능이므로 기본적으로 "기능 메모"의 고전적인 문제입니다.
참조는 지원되지 않습니다 : https://github.com/facebook/react/issues/4936
PureComponent 클래스 VS를 확장하는 컴포넌트 VS Component 클래스를 확장하는 일반적인 컴포넌트 :
구식은 구문을 PureRenderMixin
사용하여 정의 된 클래스에 첨부 할 수 있도록하는 데 사용됩니다 React.createClass
. 믹스 인은 단순히 shouldComponentUpdate
다음 소품과 다음 상태 간의 얕은 비교를 수행하여 변경된 것이 있는지 확인합니다. 아무것도 변경되지 않으면 다시 렌더링 할 필요가 없습니다.
ES6 구문을 사용하려는 경우 믹스 인을 사용할 수 없습니다. 따라서 편의상 React는 PureComponent
을 사용하는 대신 상속 할 수 있는 클래스를 도입했습니다 Component
. PureComponent
그냥 shouldComponentUpdate
같은 방식으로 구현 합니다 PureRendererMixin
. 현재 / 다음 상태와 소품 사이의 얕은 비교가 아마도 당신에게 빠른 성능 승리를 줄 수있는 가장 일반적인 시나리오이기 때문에 주로 편리한 일이므로 직접 구현할 필요가 없습니다.
예:
class UserAvatar extends Component {
render() {
return <div><img src={this.props.imageUrl} /> {{ this.props.username }} </div>
}
}
보시다시피 출력은 props.imageUrl
및에 의존합니다 props.username
. 상위 컴포넌트 <UserAvatar username="fabio" imageUrl="http://foo.com/fabio.jpg" />
에서 동일한 소품으로 렌더링 하는 render
경우 출력이 정확히 동일하더라도 React는 매번 호출 합니다. React는 dom diffing을 구현하므로 DOM은 실제로 업데이트되지 않습니다. 여전히 dom diffing을 수행하는 것은 비용이 많이들 수 있으므로이 시나리오에서는 낭비입니다.
UserAvatar
구성 요소가 PureComponent
대신 확장 되면 얕은 비교가 수행됩니다. 그리고 props와 nextProps가 동일하기 때문에 render
전혀 호출되지 않습니다.
React에서 "pure"정의에 대한 참고 사항 :
일반적으로 "순수 함수"는 동일한 입력이 주어지면 항상 동일한 결과로 평가되는 함수입니다. 출력 (React의 경우 render
메소드 가 리턴하는 결과 )은 히스토리 / 상태에 의존하지 않으며 부작용 (기능 외부에서 "세계"를 변경하는 조작)이 없습니다.
React에서 상태 비 저장 구성 요소는 호출 this.setState
하지 않고 사용하지 않는 구성 요소를 "상태 비 저장"으로 호출하는 경우 위 정의에 따라 반드시 순수한 구성 요소 는 아닙니다 this.state
.
실제로에서는 PureComponent
수명주기 방법 중에 부작용을 계속 수행 할 수 있습니다. 예를 들어 내부에 ajax 요청을 보내 componentDidMount
거나 DOM 계산을 수행하여 div의 높이를 동적으로 조정할 수 있습니다 render
.
"Dumb components"정의는 더 "실용적인"의미를 가지고 있습니다. (적어도 내가 이해한다면) 바보 같은 컴포넌트는 props를 통해 부모 컴포넌트가해야 할 일을 "알고", 일을하는 방법을 모르지만 props를 사용합니다 대신 콜백.
"스마트"의 예 AvatarComponent
:
class AvatarComponent extends Component {
expandAvatar () {
this.setState({ loading: true });
sendAjaxRequest(...).then(() => {
this.setState({ loading: false });
});
}
render () {
<div onClick={this.expandAvatar}>
<img src={this.props.username} />
</div>
}
}
"벙어리"의 예 AvatarComponent
:
class AvatarComponent extends Component {
render () {
<div onClick={this.props.onExpandAvatar}>
{this.props.loading && <div className="spinner" />}
<img src={this.props.username} />
</div>
}
}
결국 "dumb", "stateless"및 "pure"는 대부분 사용 사례에 따라 때때로 겹칠 수 있지만 반드시 그런 것은 아닙니다.