以下内容有什么不对的地方请各位多多指教。鞠躬!
1. 使用useMemo和PureComponent组件
减少组件不必要的渲染
<!--如果propsA属性有变化 componentB组件也会重新渲染-->
const app = props => {
return (
<div>
<ComponentA propsA={props.A} />
<ComponentB propsB={props.B} />
</div>
)
}
const ComponentA = props => <div>this is {props.propsA}!</div>
const ComponentB = props => <div>this is {props.propsB}!</div>
2. 避免匿名函数
<!--匿名函数不会留存在内存空间-->
const app = () => (
<div onClick={() => console.log('click')}>click</div>
)
这样写主要导致的问题就是react的重复渲染(针对无状态组件),处理方法如下
// 1. 有名函数 且 写在组件外面
const click = () => console.log('happen')
const comA = () => (
<div onClick={click}>this is comA</div>
)
// 2. useCallback
import React, { useCallback } from 'react'
const comB = () => {
const click = useCallback(()=> console.log('click'), [])
return <div onClick={click}>this is comB</div>
}
3. 避免在组件内直接使用对象
原理跟匿名函数的问题一样,对象不会留存在内存空间。即使使用pureComponent或者useMemo,react的组件依然会重新渲染!
// 错误事例
function ComponentA() {
return (
<div>
HELLO WORLD
<ComponentB style={{ {/* 避免这种情况️ */}
color: 'blue',
background: 'gold'
}}/>
</div>
);
}
function ComponentB(props) {
return (
<div style={this.props.style}>
TOP OF THE MORNING TO YA
</div>
)
}
// 解决方案
const styles = {
color: 'blue',
background: 'gold'
}
function ComponentA() {
return (
<div>
HELLO WORLD
<ComponentB style={styles}/>
</div>
);
}
function ComponentB(props) {
return (
<div style={this.props.style}>
TOP OF THE MORNING TO YA
</div>
)
}
4. 使用react.lazy和react.suspense(react 16.0 +)
使用代码分割,使打包文件体积变小,在懒加载时再加载文件,使页面加载更迅速。
import React, { lazy, Suspense } from 'react';
import Header from './Header';
import Footer from './Footer';
const BlogPosts = React.lazy(() => import('./BlogPosts'));
function MyBlog() {
return (
<div>
<Header>
<Suspense fallback={<div>Loading...</div>}> //未加载组价时
<BlogPosts />
</Suspense>
<Footer>
</div>
);
}
5. 减少频繁的挂载/卸载
频繁的挂载/卸载组件, 在组件被移除时,页面就会发生重排/重绘。
<!--错误示范-->
import React, { Component } from 'react';
import DropdownItems from './DropdownItems';
class Dropdown extends Component {
state = {
isOpen: false
}
render() {
<a onClick={this.toggleDropdown}>
Our Products
{
this.state.isOpen
? <DropdownItems>
: null
}
</a>
}
toggleDropdown = () => {
this.setState({isOpen: !this.state.isOpen})
}
}
解决方案:
通过设置css opacity: 0 或者 visiable: 'none'.
这样做会使组件留在DOM中,同时也使组件有效的消失且不增加任何的性能消耗。
6. 使用shouldComponentUpdate
react组件默认shouldComponentUpdate为true, 使用该方法可以有效地避免react组件重复渲染问题。