prosource

대응: 부모 컴포넌트는 상태 변화에 따라 변경되지 않은 아이도 모두 재생성

probook 2023. 2. 16. 21:51
반응형

대응: 부모 컴포넌트는 상태 변화에 따라 변경되지 않은 아이도 모두 재생성

아직 명확한 답을 찾지 못했습니다. 반복이 아니길 바랍니다.

간단한 채팅 앱으로 리액트+리덕스를 사용하고 있습니다.앱은 InputBar, MessageList 및 Container 구성 요소로 구성됩니다.컨테이너(상상할 수 있는 대로)는 다른 두 개의 구성요소를 랩하고 저장소에 연결됩니다.메시지 상태 및 현재 메시지(사용자가 현재 입력 중인 메시지)는 Redux 저장소에 저장됩니다.간단한 구조:

class ContainerComponent extends Component {
  ...
  render() {
    return (
      <div id="message-container">
        <MessageList 
          messages={this.props.messages}
        />
        <InputBar 
          currentMessage={this.props.currentMessage}
          updateMessage={this.props.updateMessage}
          onSubmit={this.props.addMessage}
        />
      </div>
    );
  }
}

현재 메시지를 업데이트할 때 문제가 발생합니다.현재 메시지를 업데이트하면 저장소를 업데이트하는 작업이 트리거되고 컨테이너를 통과한 소품이 다시 InputBar 구성요소로 업데이트됩니다.

단, 이 경우 매번 MessageList 컴포넌트가 재렌더되는 부작용이 있습니다.MessageList는 현재 메시지를 수신하지 않으며 업데이트할 이유가 없습니다.일단 MessageList가 커지면 현재 메시지가 업데이트될 때마다 앱 속도가 현저하게 느려지기 때문에 큰 문제입니다.

현재 메시지 상태를 InputBar 컴포넌트 내에서 직접 설정 및 업데이트(Redux 아키텍처는 완전히 무시)하여 문제를 "수정"하려고 시도했지만 가능하면 Redux 디자인 패턴을 고수하고 싶습니다.

질문은 다음과 같습니다.

  • 상위 구성 요소가 업데이트되면 React는 항상 해당 구성 요소 내의 모든 직계 하위 요소를 업데이트합니까?

  • 여기서 올바른 접근법은 무엇입니까?

상위 구성 요소가 업데이트되면 React는 항상 해당 구성 요소 내의 모든 직계 하위 요소를 업데이트합니까?

리액트는 에만 컴포넌트를 리렌더합니다. 리액트는 컴포넌트를 다시 렌더링하는 경우에만shouldComponentUpdate()true이 「」를 반환합니다true(그리고 William B가 지적한 바와 같이 DOM은 어떤 변화가 없는 한 실제로 업데이트 되지 않기 때문에 영향을 줄일 수 있습니다.)

, 「」를 가 있습니다.shouldComponentUpdate은 「」뿐입니다.true데터 ifthis.props.messages는 항상 같은 어레이이며, 다음과 같이 심플합니다.

shouldComponentUpdate(nextProps) {
    return (this.props.messages !== nextProps.messages);
}

필요에 따라 메시지 ID를 상세하게 비교하거나 비교할 수도 있습니다.

편집: 몇 년 후 많은 사람들이 기능 컴포넌트를 사용하고 있습니다.이 경우 React.memo를 확인하시기 바랍니다.기본적으로는 기능 컴포넌트는 클래스 컴포넌트의 기본 동작과 마찬가지로 매번 재렌더됩니다.사용할 수 있는 동작을 수정하려면React.memo()필요에 따라,areEqual()기능.

상위 구성 요소가 업데이트되면 React는 항상 해당 구성 요소 내의 모든 직계 하위 요소를 업데이트합니까?-> 네, 부모가 직접 변경했을 경우 디폴트로 모든 자녀는 재렌더되지만 재렌더에 의해 실제 DOM이 변경되지 않습니다(React 동작 방식). 가시적인 변경만 실제 DOM으로 갱신됩니다.

여기서 올바른 접근법은 무엇입니까?-> 가상 DOM의 재렌더링을 방지하고 성능을 더욱 향상시키려면 다음 중 하나의 방법을 따릅니다.

  1. Apply Show ComponentUpdate Lifecycle 메서드 - 이것은 자녀 컴포넌트가 클래스 기반이고 현재 소품 값을 사전 소품 값으로 확인해야 하며 true이면 false를 반환합니다.

  2. [Use Pure Component] (순수 컴포넌트 사용) -> 위의 메서드보다 단축된 버전일 뿐이며 클래스 기반 컴포넌트에서도 동작합니다.

  3. React 메모 사용 -> 기능 컴포넌트가 있어도 재렌더링을 방지하는 가장 좋은 방법입니다.컴포넌트 내보내기는 다음과 같이 React.memo로 랩핑하기만 하면 됩니다.export default React.memo(MessageList)

도움이 됐으면 좋겠네요!

부모 컴포넌트 소품이 변경된 경우 다음을 사용하여 만들어진 모든 자식 소품을 다시 렌더링합니다.React.Component진술.

한 번 만들어 보세요<MessageList>구성 요소 aReact.PureComponent이걸 피하려고.

React 문서에 따르면:In the future React may treat shouldComponentUpdate() as a hint rather than a strict directive, and returning false may still result in a re-rendering of the component.자세한 내용은 이 링크를 확인하십시오.

이것이 이 문제를 해결할 올바른 방법을 찾는 모든 사람에게 도움이 되기를 바랍니다.

사용하시는 경우map하위 구성요소를 렌더링하고 해당 구성요소에 고유한 키를 사용합니다(예:uuid()) 、 ), ),를 사용하여 다시 전환합니다.i지도에서 열쇠로요.재렌더링 문제가 해결될 수 있습니다.

이 접근법에 대해서는 확실하지 않지만 때로는 문제를 해결할 수 있습니다.

언급URL : https://stackoverflow.com/questions/40819992/react-parent-component-re-renders-all-children-even-those-that-havent-changed

반응형