zoukankan      html  css  js  c++  java
  • 【React Hooks】memo和useCallback搭配所带来的性能优化

    前言

    最近在用ts+hooks这些新特性开发新的项目,前沿的东西开发的感觉是很丝滑美妙的,时时刻刻都在踩坑,无法自拔。

    问题描述

    目录结构大概是这样的

    --RtDetail
    ----Home
    ------index.scss
    ------index.tsx
    ----Search
    ------index.scss
    ------index.tsx
    ----Detail
    ------index.scss
    ------index.tsx
    

    然后我在Home组件中引入了Search和Detail组件,伪代码大概是这样的

    /** 
     * Home.tsx 伪代码 
     * 大概就是引入了Search和Detail,给Search传入一个回调,当Search的输入框改变时候,触发更改Home中的searchId
     */
    ...
    let Home = () => {
        const [searchId, setSearchId] = useState(0)
    
        const handleSearchIdChange = (e) => {
             console.log('handleSearchChange 被创建了')
             setSearchId(e.target.value)
        }
        
        return (
            <>
                <Search handleSearchId={handleSearchId}/>
                <Detail />
            </>
        )
    }
    
    export default Home
    
    /** Search.tsx 伪代码 */
    ...
    let Search = (props: ISearchProps) => {
        
        const { handleSearchId } = props
    
        return (
            <>
                <input onChange={(e) => {handleSearchId(e)}}/>
            </>
        )
    }
    
    export default Search
    ...
    
    /** Detail.tsx */
    ...
    let Detail = () => {
    
        console.log('Detail Component 被渲染了')
        return (
            <span>test</span>
        )
    }
    
    export default Detail
    ...
    
    

    每次Search更改Home中seachId状态的时候,导致以下2个问题:

    • 1.Detail都伴随着被重新创建了,从而造成了不必要的性能浪费
    • 2.Home组件中,handleSearchId方法被重新创建

    解决方案

    memo+useCallback

    对于问题1使用memo

    /** 对Detail组件,包上一层memo,这是hooks提供的一个api */
    ...
    let Detail = memo(() => {
    
        console.log('Detail Component 被渲染了')
        return (
            <span>test</span>
        )
    })
    
    export default Detail
    
    

    React.memo类似于React.PureComponent,能对props做浅比较,防止组件无效的重复渲染!

    对于问题2使用useCallback

    /** 改写Home.tsx */
    ...
    let Home = () => {
        const [searchId, setSearchId] = useState(0)
    
        const handleSearchIdChange = (e) => {
             console.log('handleSearchChange 被创建了')
             setSearchId(e.target.value)
        }
        
        return (
            <>
                <Search handleSearchId={handleSearchId}/>
                <Detail />
            </>
        )
    }
    
    export default Home
    

    useCallback用于缓存inline函数,防止因属性更新时生成新的函数导致子组件重复渲染

  • 相关阅读:
    AppDelegate生命周期详解
    Python基础数据类型
    Linux入门基础
    mac命令节选
    如何在mac下安装android sdk
    Uiatomator2 初步探索
    Uiautumator2学习,Gradle部分
    软件测试基础方法总结
    monkey测试小结
    链表中环的入口结点
  • 原文地址:https://www.cnblogs.com/fe-linjin/p/11391967.html
Copyright © 2011-2022 走看看