React 夜點心:memo

今天的夜點心關於 React 的 memo 方法。react

先來看下面的微微微型應用,這個應用從 1 開始數數,每隔 1 秒加 1,並把當前數值的十位數和個位數經過一個名爲 Display 的子組件渲染在頁面上:git

import React, { Component, PureComponent, useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

class Displayer extends PureComponent {
  render() {
    const { name, value } = this.props;
    console.log(`render ${name} ${value}`);
    return (
      <div> <label>{name}</label> <span>{value}</span> </div>
    )
  }
}

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => setCount(prev => prev + 1), 1000);
    return () => clearInterval(timer);
  }, []);

  return (
    <div>
      <DisplayerFC name="十位" value={Math.floor(count / 10)} />
      <DisplayerFC name="個位" value={count % 10} />
    </div>
  )
}

ReactDOM.render(App, document.getElementById('#app'));
複製代碼

上面的代碼中,App 組件是應用的根組件;Display 接受一個字符串 name 和一個數字 value 做爲屬性,每次組件重渲染的時候會在控臺打印出這兩個屬性的值。github

因爲使用了 PureComponent,咱們能夠在控臺看到用來展現十位的 Display 組件只在數值的十位數變動時進行了渲染,符合預期:數組

如今咱們把 Display 組件重寫爲一個函數組件:app

const Displayer = ({ name, value }) => {
  const { name, value } = this.props;
  console.log(`render ${name} ${value}`);
  return (
    <div> <label>{name}</label> <span>{value}</span> </div>
  )
}
複製代碼

重啓應用,再看控臺:dom

此次,用來顯示十位數的組件每次都跟着父組件一塊兒從新渲染了,跟筆者最初的預期有些不一樣。React 的函數組件默認不會根據傳入的 props 是否變化選擇跳過渲染,以得到對可變數據流的兼容性,這在 Display 組件的計算開銷很是大時會帶來一些性能問題。更主要的是,看到它作了那麼多無畏的渲染,會讓做爲開發者的咱們心理很不舒服。隨着 Hooks 的推廣,愈來愈多的組件改用函數組件來實現了,該如何來改善這個性能問題呢?函數

這不,React 從 16.6 開始支持的 memo 函數就能夠幫到咱們:性能

import { memo } from 'react';
const MemoizedDislay = memo(Display);
複製代碼

只要經過 memo 函數包裹一個現成的組件(類組件或者函數組件均可以),就能夠實現相似 PureComponent 的渲染控制效果,減小沒必要要的渲染。其實 memo 函數很簡單,你能夠本身嘗試手動實現它,只要記得在比較每一個 prop 是否相等的時候使用 Object.isui

最後,memo 函數支持自定義重渲染規則,你能夠經過第二個參數傳入一個 compare 函數,告訴 memo 你但願在什麼狀況下觸發組件的重渲染,compare 函數具備以下的類型結構,入參上次的 props 和當前的 props,出參一個布爾值:this

interface Compare {
  (oldProps: Props, newProps: Props): boolean,
}
複製代碼

以上就是 React.memo 的相關內容。通常來講,只要你的應用大體遵循 immutable 的數據流,就基本能夠在全部的組件上應用這個函數來改善應用的渲染性能和你的心情。

github 原文

擴展閱讀

相關文章
相關標籤/搜索