React.memo
类似于React.PureComponent
,能对props
做浅比较,防止组件无效的重复渲染
useCallback
用于缓存inline
函数,防止因属性更新时生成新的函数导致子组件重复渲染
父组件中input值发生变化时,会导致Child重新render,使用React.memo
可以可以解决。
(最下面是完整代码,此处只是粘贴部分)
const Child = React.memo(() => {
console.log("child") //只打印一次
return (
<div>
<button >submit</button>
</div>
)
})
但是当Child组件接收父组件中的onSubmit
函数,即使用了React.memo
同样导致child重新渲染,
const Child = React.memo(({ onSubmit }) => {
console.log("child") //input变化时就打印
return (
<div>
<button onClick={onSubmit}>submit</button>
</div>
)
})
因为input变化后,生成了新的onSubmit
,React.memo
认为是不同的onSubmiit
,所以更新了
这时候,就要用到useCallback
了,
import React from "react"
const Child = React.memo(({ onSubmit }) => {
console.log("child")
return (
<div>
<button onClick={onSubmit}>submit</button>
</div>
)
})
const App = () => {
const [text, setText] = React.useState("")
// 方案一
const onSubmit1 = React.useCallback(() => {
console.log(text)
}, []) //text是初始值,没有更新
// 方案二
const onSubmit2 = React.useCallback(() => {
console.log(text)
}) //text是新的,text变化时,生成了新的onSubmit2,表示只要有属性更新就执行
// 方案三,等同于方案二
const onSubmit3 = React.useCallback(() => {
console.log(text)
}, [text]) //text是新的,text变化时,生成了新的onSubmit2,表示text更新时执行
// 方案四,达到了目的
const ref = React.useRef()
React.useLayoutEffect(() => {
ref.current = text
}, [text])
const onSubmit4 = React.useCallback(() => {
console.log(ref.current)
}, [ref]) //ref只在创建时更新,其属性current跟随text变化,不会生成新的onSubmit4
console.log("app")
return (
<div>
<input value={text} onChange={e => setText(e.target.value)} />
{/* Child组件使用了React.memo */}
<Child onSubmit={onSubmit4} />
</div>
)
}
export default App
useCallback与memo搭配使用才能达到最优效果
网友评论