React中hooks之useCallback搭配memo

2019-05-19  本文已影响0人  小猪佩奇的王子
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搭配使用才能达到最优效果

上一篇下一篇

猜你喜欢

热点阅读