React 组件渲染优化

如何确定按钮被重新渲染了? 直观的颜色表示重新渲染了。

函数式组件版本

// The type of the props type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> // A memoized button with a random background colour const randomColor = () => Math.round(Math.random() * 255) const Button = React.memo((props: ButtonProps) => ( <button type="button" onClick={props.onClick} style={{ border: '1px solid #ccc', borderRadius: '3px', padding: '10px', marginRight: '5px', background: `rgb(${randomColor()}, ${randomColor()}, ${randomColor()})`, }} > {props.children} </button> ))

PureComponent 版本

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> class Button extends React.Component<ButtonProps, {}> { static randomColor() { return Math.round(Math.random() * 255) } shouldComponentUpdate(nextProps: ColorButtonProps, nextState: any) { const { onClick } = this.props if (onClick !== nextProps.onClick) { return true } return false } render() { const { onClick, children } = this.props return ( <button type="button" onClick={onClick} style={{ border: '1px solid #ccc', borderRadius: '3px', padding: '10px', marginRight: '5px', background: `rgb(${ColorButton.randomColor()}, ${ColorButton.randomColor()}, ${ColorButton.randomColor()})`, }} > {children} </button> ) } }

使用 useCallback 缓存状态修改函数

import React, { useState, useCallback } from 'react' // Keeps track of all created functions during the app's life const functions: Set<any> = new Set() function App() { const [delta, setDelta] = useState(1) const [c, setC] = useState(0) const incrementDelta = useCallback(() => setDelta((delta0) => delta0 + 1), []) const increment = useCallback(() => setC((c0) => c0 + delta), [delta]) // Register the functions so we can count them functions.add(incrementDelta) functions.add(increment) return ( <> <div> <div> Delta is {delta} </div> <div> Counter is {c} </div> <br /> <div> <ColorButton onClick={incrementDelta}>Increment Delta</ColorButton> <ColorButton onClick={increment}>Increment Counter</ColorButton> </div> <br /> <div> Newly Created Functions: {functions.size - 2} </div> </div> <Switch> <Route path="/" exact component={withBasicLayout(Home)} /> <Route path="/history" component={withBasicLayout(History)} /> <Route path="/lock" component={LockScreen} /> </Switch> </> ) } export default App

遗留问题

React.StrictMode 导致 memo 无效

参考

  1. [React’s useCallback and useMemo Hooks By Example](

© 2021, XZD