1、概述
React为什么要掌握性能优化。如下图,我们只修改了Content的内容啊,为什么Header组件和Comment组件依然执行了,能打印出内容。
我们写的代码
import React, { useState } from 'react'
export default function App() {
const [num, setNum ] = useState(0)
return (
<div>
<input value={num} onChange={(e) => setNum(e.target.value)}></input>
<p>num is {num}</p>
<ExpensiveComp/>
</div>
)
}
function ExpensiveComp() {
console.log('运行了无关组件')
return <p>无关组件</p>
}
调试结果
结论
每次改变输入框的内容都会让我们的整个页面全部遍历
2、原因
因为我们将变的部分和不变的部分是糅合在一起的,什么是变化的部分呢?
主要是这3个属性props、state、context。根本就是state改变了,导致当前页面的重新渲染。如果把没有关系的状态分割开呢
代码优化
export default function App() {
return (
<div>
<InputNum/>
<ExpensiveComp />
</div>
)
}
function InputNum() {
//状态抽离
const [num, setNum] = useState(0)
return (
<>
<input value={num} onChange={(e) => setNum(e.target.value)}></input>
<p>num is {num}</p>
</>
)
}
function ExpensiveComp() {
console.log('运行了无关组件')
return <p>无关组件</p>
}
调试结果
3、其他情况怎么将状态抽离开
1、状态在父组件中
export default function App() {
const [num, setNum] = useState(0)
return (
<div title={num + ''}>
<input value={num} onChange={(e) => setNum(e.target.value)}></input>
<p>num is {num}</p>
<ExpensiveComp />
</div>
)
}
function ExpensiveComp() {
console.log('运行了无关组件')
return <p>无关组件</p>
}
优化---ExpensiveComp组件的props是没有改变的不应该更新
export default function App() {
//没有状态了,
return (
<InputWrapper>
<ExpensiveComp/>
</InputWrapper>
)
}
function InputWrapper(props) {
const [num, setNum] = useState(0)
return (
<div title={num + ''}>
<input value={num} onChange={(e) => setNum(e.target.value)}></input>
<p>num is {num}</p>
{props.children}
</div>
)
}
2、使用cotext的时候怎么优化
问题代码
const numCtx = React.createContext(0)
const updateNumCtx =React.createContext(()=>{})
export default function App() {
const [num, setNum] = useState(0)
return (
<numCtx.Provider value={num}>
<updateNumCtx.Provider value={setNum}>
<ExpensiveComp/>
</updateNumCtx.Provider>
</numCtx.Provider>
)
}
function ExpensiveComp() {
return (
<>
<Button/>
<Show/>
</>
)
}
function Button() {
const updateNum = useContext(updateNumCtx)
console.log('btn')
return (
<button onClick={() => updateNum(Math.random())}>产生随机数</button>
)
}
function Show(){
const num = useContext(numCtx)
console.log('show')
return (
<p>num is {num}</p>
)
}
优化代码 --- 可以考虑优化api,
只有使用优化api包裹一下就能够命中React的优化策略
function ExpensiveComp() {
return useMemo(()=>{
return <>
<Button />
<Show />
</>
},[])
}