React性能优化

React性能优化

memo: 包装组件
useMemo :包装传参(除函数)
useCallback:包装函数传递

一、 组件的优化(没有任何传值,单纯的调用)
例:

import React, { useState } from 'react'
import Child from './child'
export default function Parent(props: any) {
	const [num, setNum] = useState(0)
	const handleClick = () => {
		setNum(num + 1)
	}
	return (
		<div>
			<h2>{num}</h2>
			<button onClick={handleClick}>更改num</button>
			{/* 引用子组件 */}
			<Child />
		</div>
	)
}

子组件:

export default function Child(props: any) {
	console.info('子组件渲染了')
	return <div>我是子组件</div>
}

调用结果,子组件跟随父组件渲染了,造成了不必要的性能浪费

优化组件的渲染:
使用react的memo来控制子组件的渲染(原理: 对子组件的props进行浅比较)
改造后的组件展示:

import React, { useState } from 'react'
import React, { useState, memo } from 'react' // 也可以直接导入memo
import Child from './child'

const MemoChild = React.memo(Child) // 新增代码,使用memo处理子组件
// 或者
const MemoChild memo(Child) // 新增代码,使用memo处理子组件

export default function Parent(props: any) {
	const [num, setNum] = useState(0)
	const handleClick = () => {
		setNum(num + 1)
	}
	return (
		<div>
			<h2>{num}</h2>
			<button onClick={handleClick}>更改num</button>
			{/* 引用子组件 */}
			{/* <Child />   */}
			{/* 新增代码 */}
			<MemoChild /> 
		</div>
	)
}
此时子组件就不会跟随父组件的渲染而渲染

二、 子组件传入了处理函数

单纯的使用memo依然会使子组件多次渲染,这是就是用hooks中的useCallback
因为父组件的渲染使函数再次注册了一次。所以导致传入子组件的props改变加粗样式了

分析原因: 首先一个组件重新渲染,一般是三种情况导致的:
1.组件自己的状态改变了
2.父组件重新渲染,但父组件的 props 没有改变
3.父组件重新渲染,父组件传递的 props 改变

组件自己的状态改变了 父组件重新渲染,但父组件的 props 没有改变
父组件重新渲染,父组件传递的 props 改变 很明显,第一种不是,因为子组件并没有任何状态。
第二种,已经用 React.memo 优化掉了,所以也不是。
那说明就是第三种, 传递的 props 改了。

// 新增引入 useCallback
import React, { useState, useCallback } from 'react'
import Child from './child'
const MemoChild = React.memo(Child) 
export default function Parent(props: any) {
	const [num, setNum] = useState<number>(0)
	const handleClick = () => {
		setNum(num + 1)
	}
  // 修改代码
  // 通过 useCallback 进行记忆 handleChange, 并将记忆的 handleChange 传递给 MemoChild
	const memoizedCallback = useCallback(() => {
		console.info(2323)
	},[])
	return (
		<div>
			<h2>{num}</h2>
			<button onClick={handleClick}>更改num</button>
			{/* 引用子组件 */}
			<MemoChild handleChange={memoizedCallback} />
		</div>
	)
}

三、子组件接收参数(对象形式传输 )
因为对props 浅比较,所以当以对象像是传输时,浅比较失效。导致子组件渲染
所以使用useMemo 来处理传参

import React, { useState,useMemo } from 'react'
import Child from './child'
const MemoChild = React.memo(Child)
export default function Parent(props: any) {
	const [num, setNum] = useState<number>(0)
	const handleClick = () => {
		setNum(num + 1)
	}
	return (
		<div>
			<h2>{num}</h2>
			<button onClick={handleClick}>更改num</button>
			{/* 采用 useMemo */}
			<MemoChild person={useMemo(()=>({name:"张三"}),[])} />
		</div>
	)
}

四、综合所有的情况

import React, { useState,useMemo,useCallback,memo } from 'react'
import Child from './child'
const MemoChild = memo(Child) // 包装子组件
export default function Parent(props: any) {
	const [num, setNum] = useState<number>(0)
	const handleClick = () => {
		setNum(num + 1)
	}
	const memoizedCallback = useCallback(() => {
	console.log(4444)},[])  // 包装函数
	
	return (
		<div>
			<h2>{num}</h2>
			<button onClick={handleClick}>更改num</button>
			{/* 采用 useMemo */}
			<MemoChild person={useMemo(()=>({name:"张三"}),[])} onChang={memoizedCallback} />
		</div>
	)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值