>  기사  >  웹 프론트엔드  >  React_javascript 팁에서 다시 렌더링을 방지하는 방법

React_javascript 팁에서 다시 렌더링을 방지하는 방법

不言
不言원래의
2018-04-10 15:12:441258검색

이 글은 주로 React에서 재렌더링을 피하는 방법을 소개하고 있습니다. 이제 여러분과 공유하고, 도움이 필요한 친구들을 위한 참고 자료로도 사용할 수 있습니다.

컴포넌트 재렌더링

모든 소품을 저장할 수 있습니다. React 컴포넌트의 Type 데이터를 사용하면 props와 state를 변경하여 전체 컴포넌트의 상태를 제어할 수 있습니다. props와 state가 변경되면 React는 전체 컴포넌트를 다시 렌더링합니다. 컴포넌트 다시 렌더링 프로세스는 아래와 같이 단순화될 수 있습니다.

번역가의 diff에 대한 이전 이해는 props를 변경하는 컴포넌트의 경우 diff가 가능하다는 것입니다. 자동으로 계산됩니다. 컴포넌트 내부의 DOM 트리에서 차이점을 감지하고 이를 비교하여 실제로 변경된 DOM 노드를 찾아 변경된 부분을 렌더링합니다. 이는 잘못된 이해입니다. diff 알고리즘은 상태나 소품을 변경하는 구성 요소/가상 노드를 계산하는 데만 사용되며, 이 구성 요소/가상 노드는 아무리 크더라도 다시 렌더링됩니다.

아래와 같이 렌더링된 구성 요소가 있다고 가정합니다.

다음으로 상태 변경으로 인해 아래 그림의 녹색 노드를 아래와 같이 다시 렌더링해야 합니다.

일반적인 생각은 업데이트만 하면 된다는 것입니다. 아래 세 개의 녹색 노드만 구성 요소 업데이트를 완료할 수 있습니다

그러나! 컴포넌트의 props나 상태가 변경되면 전체 컴포넌트가 다시 렌더링되므로 위에서 언급한 세 개의 녹색 노드 외에도 모든 노란색 노드도 다시 렌더링해야 합니다

렌더링해야 하는 세 개의 노드에는 다른 불필요한 렌더링 노드도 렌더링되어 성능이 크게 낭비됩니다. 복잡한 페이지의 경우 이로 인해 전반적인 페이지 경험이 매우 저하됩니다. 따라서 구성 요소의 성능을 향상하려면 불필요한 렌더링을 줄이기 위해 할 수 있는 모든 작업을 수행해야 합니다.

shouldComponentUpdate

shouldComponentUpdate이 함수는 구성 요소가 다시 렌더링되기 전에 호출됩니다. 함수의 반환 값에 따라 구성 요소를 다시 렌더링해야 하는지 여부가 결정됩니다. 함수의 기본 반환 값은 true입니다. 즉, 구성 요소의 props나 상태가 변경되는 한 가상 DOM이 다시 빌드된 다음 diff 알고리즘을 사용하여 비교되고 비교 결과에 따라 결정됩니다. 전체 구성 요소를 다시 렌더링할지 여부입니다. 함수의 반환 값은 false입니다. 이는 다시 렌더링이 필요하지 않음을 의미합니다.

이 함수는 기본적으로 true를 반환합니다.

PureRenderMixin

React는 공식적으로 PureRenderMixin 플러그인을 제공합니다. 이 플러그인의 기능은 필요하지 않을 때 shouldComponentUpdate 함수가 false를 반환하도록 하는 것입니다. 불필요한 재렌더링을 줄이고 어느 정도의 성능 향상을 얻으려면 사용 방법은 다음과 같습니다.

  import PureRenderMixin from 'react-addons-pure-render-mixin';
  class FooComponent extends React.Component {
   constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
   }

   render() {
    return <p className={this.props.className}>foo</p>;
   }
  }

PureRenderMixin 소스 코드의 PureRenderMixin.shouldComponentUpdate 정의를 다시 작성해야 합니다.

  shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  }

Rewrite 이 방법에서는 컴포넌트의 현재 상태와 다음 컴포넌트의 상태를 기반으로 얕은 비교가 이루어지며, 컴포넌트의 상태가 변경되면 반환 결과는 false입니다. 상태가 변하지 않으면 반환 결과는 true

  shouldComponentUpdate(nextProps, nextState) {
    return !shallowEqual(this.props, nextProps) ||
        !shallowEqual(this.state, nextState);
  }

입니다. 최신 버전에서는 이 플러그인을 사용하지 않고도 React.PureComponent의 기본 클래스만 제공됩니다.

번역가의 참고: 따라서 더 큰 구성 요소가 다시 렌더링하기로 결정하면 새로운 shouldComponentUpdate 메서드를 각 하위 구성 요소에 바인딩하여 하위 구성 요소의 다시 렌더링 횟수를 줄일 수 있습니다.

우리는 무엇이든 비교할 수 있도록 shouldComponentUpdate 함수를 직접 다시 작성할 수 있습니다. 즉, 심층 비교(레이어별 재귀를 통한 비교)는 시간이 많이 걸리고 일반적으로 권장되지 않습니다. 비교에 소요되는 시간이 전체 구성 요소를 다시 렌더링하는 데 소요되는 시간보다 적은지 확인하는 데 필요합니다. 동시에 비교에 소요되는 시간을 줄이려면 props와 상태가 최대한 단순하도록 해야 합니다. , 불필요한 속성을 상태에 두지 마세요. 다른 속성에서 계산된 속성은 상태에 두어서는 안 됩니다.

Immutable.js

복잡한 데이터를 비교하는 것은 시간이 많이 걸리고 비교할 수 없을 수도 있습니다. 이 문제는 Immutable.js를 사용하면 잘 해결될 수 있습니다. 객체에 대해서는 참조가 반환되고, 변경된 객체에 대해서는 새 참조가 반환됩니다. 따라서 상태 비교를 위해서는 다음 코드만 사용하면 됩니다.

  shouldComponentUpdate() {
    return ref1 !== ref2;
  }

또한 하위 구성 요소의 shouldComponentUpdate 메서드를 다시 작성해야 합니다.

순수 구성 요소

如果一个组件只和 props 和 state 有关系,给定相同的 props 和 state 就会渲染出相同的结果,那么这个组件就叫做纯组件,换一句话说纯组件只依赖于组件的 props 和 state,下面的代码表示的就是一个纯组件。

   render() {
     return (
       <p style={{width: this.props.width}}>
           {this.state.rows}
       </p>
     );
  }

如果某个子组件的 props 是固定的不会发生变化,我们叫做无状态组件。在这个组件里面使用 pureRenderMixin 插件,能够保证 shouldComponentUpdate 的返回一直为 false。所以,分清纯组件和无状态组件,在无状态组件中重写shouldComponentUpdate方法是最好的选择。

key

在写动态子组件的时候,如果没有给动态子项添加key prop,则会报一个警告。这个警告指的是,如果每一个子组件是一个数组或者迭代器的话,那么必须有一个唯一的key prop,那么这个key prop是做什么的呢?
我们想象一下,假如需要渲染一个有5000项的成绩排名榜单,而且每隔几秒就会更新一次排名,其中大部分排名只是位置变了,还有少部分是完全更新了,这时候key就发挥作用了,它是用来标识当前的唯一性的props。现在尝试来描述这一场景

  [{
   sid: &#39;10001&#39;,
   name: &#39;sysuzhyupeng&#39;
  }, {
   sid: &#39;10008&#39;,
   name: &#39;zhyupeng&#39;
  }, {
   sid: &#39;120000&#39;,
   name: &#39;yupeng&#39;
  }]

其中sid是学号,那么我们来实现成绩排名的榜单

  import React from &#39;react&#39;;
  function Rank({ list }){
    return (
     <ul>
       {list.map((entry, index)=>(
         <li key={index}>{entry.name}</li>
       ))}
     </ul>
    )
  }

我们把key设成了序号,这么做的确不会报警告了,但这样是非常低效的做法,这个key是用来做virtual Dom diff的,上面的做法相当于用了一个随机键,那么不论有没有相同的项,更新都会重新渲染。

正确的做法非常简单,只需要把key的内容换成sid就可以了。

那么还有另一个问题,当key相同的时候,React会怎么渲染呢,答案是只渲染第一个相同key的项,且会报一个警告。

相关推荐:

代码详解React Js 微信分享封装

在React里使用Vuex的具体步骤

react怎样实现页面代码分割和按需加载

위 내용은 React_javascript 팁에서 다시 렌더링을 방지하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.