生活随笔
收集整理的這篇文章主要介紹了
react --- render持续调用解决方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題描述:
- 在某個組件中.有可能頻繁的取數據(但是數據未改變,因此不需要更新).
- 數據的頻繁請求會觸發render函數,造成性能消耗
- 模擬代碼如下
export class CommentList extends Component {constructor(props
) {super(props
);this.state
= {comments
: []}}componentDidMount() {setInterval(() => {this.setState({comments
:[{ body
: '奇怪的栗子', author
: 'odd marron'},{ body
: '好吃的栗子', author
: 'nice marron'}]})}, 1000)}render() {return (<div
>{this.state
.comments
.map((c
,i
)=>(<Comment key
={i
} data
={c
} />))}</div
>)}
}class Comment extends React.Component{console
.log('render comment');render(){return (<div
><p
> {this.props
.data
.body
} </p
><p
> --- {this.props
.data
.author
} </p
></div
>)}
}
解決方案1
- React 15.3之前(無PureComponent)
- 使用shouldComponentUpdate
- 在shouldComponentUpdate中判斷當前body是否和傳入的數據相等.
class Comment extends React.Component{shouldComponentUpdate(nextProps) {if(nextProps.data.body === this.props.data.body &&nextProps.data.author === this.props.data.author) {return false;}return true;}render() {return (<div><p> {data.body} </p><p> --- {data.author} </p></div>);}
}
解決方案2
- PureComponent解決方案
- 對上面代碼修改后如下
import React, { Component } from 'react';// 容器組件
export class CommentList extends Component {constructor(props) {super(props);this.state = {comments: []};}componentDidMount() {setTimeout(() =>{this.setState({comments: [{ body: "奇怪的栗子" , author: "odd marron" },{ body: "好吃的栗子", author: "nice marron" }]});}, 1000)}render() {return (<div>{this.state.comments.map((c,i) => (<Comment key={i} {...c} />))}</div>);}
}
// 展示組件
class Comment extends React.PureComponent{render() {console.log('render comment');return (<div><p>{this.props.data.body}</p><p>--- {this.props.data.author}</p></div>)}
}
注意:
- 使用PureComponent時,其傳遞的參數只能是基本類型引用或簡單的非多層嵌套對象
- 原因見下面PureComponent源碼:
import shallowEqual
from './shallowEqual'
import Component
from './Component'export default function PureComponent(props
, context
) {Component
.call(this, props
, context
);
}PureComponent
.prototype
= Object
.create(Component
.prototype
);
PureComponent
.prototype
.constructor
= PureComponent
;
PureComponent
.prototype
.isPureReactComponent
= true;
PureComponent
.prototype
.shouldComponentUpdate
= shallowCompare
;function shallowCompare (nextProps
, nextState
) {return !shallowEqual(this.props
, nextProps
) ||!shallowEqual(this.state
, nextState
);
}export default function shallowEqual(objA
, objB
) {if(objA
=== objB
){return true}if(typeof objA
!=='object' || obja
=== null || typeof objB
!== 'objB' || objB
=== null) {return false}var keysA
= Object
.keys(objA
);var keysB
= Object
.keys(objB
);if(keysA
.length
!== keysB
.length
){return false}for(var i
= 0; i
< keysA
.length
; i
++ ){if(!objB
.hasOwnproperty(keysA
[i
]) || objA
[keysA
[i
]] !== objB
[krysA
[i
]] ){return false;}}return true;
}
- PureComponent 對shouldComponentUpdate進行設置.
- 比較引用地址然后比較第一層…
- 因此使用PureComponent時,應注意將對象結構出來使用
解決方案3
- React.memo (React v16.6.0以上)
- React.memo是個高階函數
- 更改上面Comment
const Comment
= React
.memo((props
) => {console
.log('render comment');return (<div
><p
>{props
.body
}</p
><p
> --- {props
.author
}</p
></div
>)
});
總結
以上是生活随笔為你收集整理的react --- render持续调用解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。