目录
性能优化_shouldComponentUpdate
当一个组件的 props 或 state 变更,React 会将最新返回的元素与之前渲染的元素进行对比,以此决定是否有必要更新真实的DOM。当它们不相同时,React 会更新该 DOM。
shouldComponentUpdate 方法会在重新渲染前被触发。其默认实现总是返回 true ,让 React 执行更新。
如果有些情况下你的组件不需要更新,你可以在 shouldComponentUpdate 中返回 false 来跳过整个渲染过程。
//ColorButtonParent.js
import React, { Component } from 'react';
import ColorButton from './ColorButton';
export default class ColorButtonParent
extends Component {
constructor(){
super()
this.state={color:'#ccc',count:0}
}
render() {
return (
<div>
<button onClick= {()=>this.setState({color:'pink'})} style={
{color:this.state.color}}>变色</button>
<button onClick= {()=>this.setState({count:this.state.count+1})} >变量</button>
<h3>数量:{this.state.count}</h3>
<ColorButton color= {this.state.color}/>
</div>
);
//ColorButton.js
import React, { Component } from 'react';
export default class ColorButton extends Component {
shouldComponentUpdate(nextProps){
//只有传递过来的color更改了,才更新,父组件其他状态变更了,不更新
if(this.props.color !== nextProps.color){
return true
}
return false
}
render() {
console.log('ColorButton重新渲染了')
return (
<button style= {
{color:this.props.color}}>跟着变色</button>
);
}
}
性能优化_时间分片
我们必须要明白的一个道理,js执行永远要比dom渲染快的多。 所以对于大量的数据,一次性渲染,容易造成卡顿,卡死的情况。
import React, { Component } from 'react';
export default class LargeDom extends Component {
constructor(){
super()
this.state={list:[]}
}
componentDidMount(){
this.setState({list:new Array(40000).fill(0)})
}
render() {
return (
<div>
{this.state.list.map((item,index)=><li key= {index}>
这是第{index+1}条数据
</li>)}
</div>
);
}
}
import React, { Component } from 'react';
export default class LargeDom extends
Component {
constructor(){
super()
this.state={list:[]}
}
componentDidMount(){
this.preList=new Array(40000).fill(0)//定义初始的40000条数据
this.sliceTime(0)
}
//时间分片,每一次渲染100条数据,渲染400次
sliceTime=(times)=>{
console.log('times',times)
if(times==400) {
return
}
setTimeout(()=>{
const sliceList=this.preList.slice(times*100,((times+1)*100))
this.setState({list:this.state.list.concat(sliceList)})
this.sliceTime(times+1)
},0)
}
render() {
return (
<div>
{this.state.list.map((item,index)=><li key= {index}>
这是第{index+1}条数据
</li>)}
</div>
);
}
}
性能优化_虚拟列表
虚拟列表是按需显示的一种技术,不必渲染所有列表项,而只是渲染可视区域内的一部分列表元素的技术。
可以使用 react-virtualized 虚拟滚动库。
npm install react-virtualized
import React, { Component } from 'react';
import {List ,AutoSizer} from 'react-virtualized'
export default class LargeDom extends
Component {
constructor(){
super()
this.state={list:[]}
}
componentDidMount(){
this.setState({list:new Array(40000).fill(0)})
}
render() {
return (
<div style= {
{height:'600px',border:'1px solid red'}}>
<AutoSizer>
{({width,height})=>{
return <List
width={width}
height={height}
rowCount= {this.state.list.length}
rowHeight={50}
rowRenderer= {({key,index,style})=><li key={key} style={style}>
这是第{index+1}条数据
</li>}
/>
}}
</AutoSizer>
</div>
);
}
}
PropTypes 进行类型检查
组件可以通过props传递数据,针对传递的数据类型我们可以进行类型检查,有益于在代码运行前识别某些类型的问题。在组件的 props 上进行类型检查,要引用 prop-types 库提供一系列验证器:
import PropTypes from 'prop-types';
//PropTypesTest.js
import PropTypes from 'prop-types';
export default class PropTypesTest extends
React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
PropTypesTest.propTypes = {
name: PropTypes.string
};
//App.js
<PropTypesTest name={
{name:'xiaotong'}}/>
提示:
当传入的 prop 值类型不正确时,JavaScript 控制台将会显示警告。
出于性能方面的考虑, propTypes 仅在开发模式下进行检查。
propTypes提供的验证器:
PropTypes.array PropTypes.bool PropTypes.func PropTypes.number PropTypes.object PropTypes.string PropTypes.symbol // 任何可被渲染的元素(包括数字、字符串、元素或数组) // (或 Fragment) 也包含这些类型。 PropTypes.node // 一个 React 元素。 PropTypes.element // 一个 React 元素类型(即,MyComponent)。 PropTypes.elementType, // 你也可以声明 prop 为类的实例,这里使用 // JS 的 instanceof 操作符。 PropTypes.instanceOf(Message) // 你可以让你的 prop 只能是特定的值,指定它为 // 枚举类型。 PropTypes.oneOf(['News', 'Photos']) // 一个对象可以是几种类型中的任意一个类型 PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.instanceOf(Message) ]) // 可以指定一个数组由某一类型的元素组成 PropTypes.arrayOf(PropTypes.number) // 可以指定一个对象由某一类型的值组成 PropTypes.objectOf(PropTypes.number), // 可以指定一个对象由特定的类型值组成 PropTypes.shape({ color: PropTypes.string, fontSize: PropTypes.number }) // 你可以在任何 PropTypes 属性后面加上`isRequired` ,确保 // 这个 prop 没有被提供时,会打印警告信息。 PropTypes.func.isRequired // 任意类型的数据 PropTypes.any.isRequired
默认 Prop 值
可以通过配置特定的 defaultProps 属性来定义 props 的默认值。
import React from 'react';
import PropTypes from 'prop-types';
export default class PropTypesTest extends
React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
PropTypesTest.propTypes = {
name: PropTypes.string
};
PropTypesTest.defaultProps={
name:'默认值'
}
提示:
类型检查也适用于 defaultProps 。
TypeScript 类型检查
TypeScript 是一种由微软开发的编程语言。它是 JavaScript 的一个类型超集,包含独立的编译器。作为一种类型语言,TypeScript 可以在编译时发现 bug 和错误,这样程序运行时就可以避免此类错误。
npx create-react-app my-ts-app --template typescript
import React, { Component } from 'react'
//定义props的类型
type Props={
name:string
}
export default class Test extends
Component<Props> {
render() {
return (
<div>{this.props.name}</div>
)
}
}
//App.js
<Test name={
{name:'xiaotong'}}/>