이번에는 반복 렌더링을 금지하는 React 설정에 대해 알려드리겠습니다. 반복 렌더링을 금지하는 React 설정의 주의사항은 무엇인가요?
컴포넌트 다시 렌더링
React 컴포넌트의 props 및 state에 모든 유형의 데이터를 저장할 수 있으며, props 및 state를 변경하여 전체 컴포넌트의 상태를 제어할 수 있습니다. props와 state가 변경되면 React는 전체 컴포넌트를 다시 렌더링합니다. 컴포넌트 다시 렌더링 프로세스는 아래와 같이 단순화될 수 있습니다.
번역가의 diff에 대한 이전 이해는 props를 변경하는 컴포넌트의 경우 diff가 가능하다는 것입니다. 자동으로 계산됩니다. 컴포넌트 내부의 DOM 트리에서 차이점을 감지하고 이를 비교하여 실제로 변경된 DOM 노드를 찾아 변경된 부분을 렌더링합니다. 이는 잘못된 이해입니다. diff 알고리즘은 상태나 소품을 변경하는 구성 요소/가상 노드를 계산하는 데만 사용되며, 이 구성 요소/가상 노드는 아무리 크더라도 다시 렌더링됩니다.
아래와 같이 렌더링된 구성 요소가 있다고 가정합니다.
다음으로 상태 변경으로 인해 아래 그림의 녹색 노드를 아래와 같이 다시 렌더링해야 합니다.
The 일반적인 생각은 다음 항목만 업데이트하면 된다는 것입니다. 세 개의 녹색 노드가 구성 요소 업데이트를 완료할 수 있습니다
그러나! 컴포넌트의 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); }
재작성된 메소드는 컴포넌트의 현재 상태를 기반으로 합니다. 컴포넌트의 상태가 변경되면 반환 결과는 false입니다.
shouldComponentUpdate(nextProps, nextState) { return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); }
최신 버전의 React에서는 React.PureComponent의 기본 클래스가 제공되므로 이 플러그인을 사용할 필요가 없습니다.
번역가의 메모: 따라서 더 큰 구성 요소가 다시 렌더링하기로 결정하면 새로운 shouldComponentUpdate 메서드를 각 하위 구성 요소에 바인딩하여 하위 구성 요소의 다시 렌더링 횟수를 줄일 수 있습니다.
我们自己可以重写 shouldComponentUpdate 这个函数,使得其能够对任何事物进行比较,也就是深比较(通过一层一层的递归进行比较),深比较是很耗时的,一般不推荐这么干,因为要保证比较所花的时间少于重新渲染的整个组件所花的时间,同时为了减少比较所花的时间我们应该保证 props 和 state 尽量简单,不要把不必要的属性放入 state,能够由其他属性计算出来的属性也不要放入 state 中。
Immutable.js
对于复杂的数据的比较是非常耗时的,而且可能无法比较,通过使用 Immutable.js 能够很好地解决这个问题,Immutable.js 的基本原则是对于不变的对象返回相同的引用,而对于变化的对象,返回新的引用。因此对于状态的比较只需要使用如下代码即可:
shouldComponentUpdate() { return ref1 !== ref2; }
同样需要我们在子组件中将shouldComponentUpdate方法重写。
Pure Component
如果一个组件只和 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: '10001', name: 'sysuzhyupeng' }, { sid: '10008', name: 'zhyupeng' }, { sid: '120000', name: 'yupeng' }]
其中sid是学号,那么我们来实现成绩排名的榜单
import React from 'react'; 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的项,且会报一个警告。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 React 설정은 반복 렌더링을 금지합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!