类组件

  1. React. PureComponent
// class Hello extends React.Component { // 普通组件
class Hello extends React.PureComponent { // 纯组件
    render() {
        return (
        	<div>纯组件</div>
        )
    }
}
  1. shouldComponentUpdate
class Hello extends Component {
    shouldComponentUpdate(props,state) {
        // 根据条件,决定是否重新渲染组件
        return false
    }
    render() {…}
}

hooks组件

  1. useCallback/useMemo和memo组合,防止父组件re-render后,导致自己的函数或者值
    首先,假如我们不使用useCallback,在父组件中创建了一个名为handleClick的事件处理函数,根据需求我们需要把这个handleClick传给子组件,当父组件中的一些state变化后(这些state跟子组件没有关系),父组件会reRender,然后会重新创建名为handleClick函数实例,并传给子组件,这时即使用React.memo把子组件包裹起来,子组件也会重新渲染,因为props已经变化了,但这个渲染是无意义的

    如何优化呢?这时候就可以用useCallback了,我们用useCallback把函数包起来之后,在父组件中只有当deps变化的时候,才会创建新的handleClick实例,子组件才会跟着reRender
    (注意,必须要用React.memo把子组件包起来才有用,否则子组件还是会reRender。React.memo是类似于class组件中的Pure.Component的作用)

这个的具体使用方式可以看我其他关于其三个专门文章

  1. useRef解决方案
    • useRef在每次reRender时不会改变,保证了父组件不会重新创建handleClick函数实例,handleClick函数能拿到最新的state
const [text, setText] = useState('Initial value');
const textRef = useRef(text);
const handleClick= useCallback(() => {
     console.log(textRef.current);
 }, []); 

 useEffect(() => {
     console.log('update text')
     textRef.current = text;
 }, [text])

3.useReducer解决方案

  • dispatch自带memoize,所以子组件不会进行 re-render
function reducer(state, action) {
    switch(action.type) {
        case 'update':
            return action.preload;
        case 'childComponent':
            // 要执行的函数  
            return state;     
    }
}
export default function Index() { // 父组件
    const [state, dispatch] = useReducer(reducer, 'Initial value');

    return (
        <>
            <input value={state} onChange={(e) => dispatch({
                type: 'update', 
                preload: e.target.value
            })} />
            <ChildComponent dispatch={dispatch} />
        </>
    )
}

//在 ChildComponent中,拿到dispatch,通过dispatch({type: 'childComponent' })的方式调用

posted on 2022-06-13 15:37  94Lucky  阅读(221)  评论(0编辑  收藏  举报