react性能优化之render

两个相互关联的组件想要共享状态,咱们会想到提高状态到俩组件最近的父级节点

1、一般我会会在父级设置状态,两个子组件共享父组件的状态,一般的作法是:
 1. 父组件设置状态,俩子组件接收props 🤔
... 这种状况会是:其中任何一个子组件的改变,都会形成整个父级组件的重渲染 render。
 2. 父组件不设置状态,俩子组件不接收props, 组件树的顶层使用 React Context
来共享数据 🤔
... 这种状况会是:只要提供给 Provider 的值发生变化,全部消费到了 Provider 的后代组件都会发生重渲染 render。

2、咱们要怎样才能共享状态,又不会形成重渲染 render🤔️,这里咱们就要用的 useRef

“当 ref 对象内容发生变化时,useRef 并不会通知变动。变动 .current 属性不会引起组件
从新渲染。” —— React 文档
 1. 父组件建立ref 对象,俩子组件接收父组件建立的ref,这样子组件拿到变动 .current
 ,下面经过一个🌰:(这里咱们经过Provider的)
一个简单的星期英文翻译:

translateContext.jsxhtml

import { createContext, useContext, useRef } from "react";

export const translateContext = createContext({});

export const useTranslateContext = () => useContext(translateContext);


export const TranslateProvider = ({ children }) => {
    const translateRef = useRef({});
    return (
        <translateContext.Provider value={{translateRef}}>
            {children}
        </translateContext.Provider>
    )
}
复制代码

translate.jsxreact

import { useState } from 'react';
import { TranslateProvider, useTranslateContext } from './translateContxt';
const dict = {
    '周一': 'Monday',
    '周二': 'Tuesday',
    '周三': 'Wednesday',
    '周四': 'Thursday',
    '周五': 'Friday',
    '周六': 'Saturday',
    '周日': 'Sunday',
}

const CnTranslate = () => {
    const { translateRef } = useTranslateContext();
    const onChange = (e) => {
        const { value } = e.target;
        translateRef.current.value = value;
    }
    const translate = () => {
        translateRef.current.setTranslate(false);
        setTimeout(() => {
            translateRef.current.setTranslate(true)
        }, 100)
    }
    return (
        <div style={{ flex: '1', background: "#fff", margin: '10px', textAlign: 'center' }}>
            <input type="text" onChange={onChange}/>{' '}
            <button onClick={translate}>翻译</button>
        </div>
    )
}

const EnTranslate = () => {
    const [translate, setTranslate] = useState(false);
    const { translateRef } = useTranslateContext();
    translateRef.current.setTranslate = setTranslate;
    return (
        <div style={{ flex: '1', background: "#fff", margin: '10px', textAlign: 'center'}}>
            {translate && (<span>{dict[translateRef.current.value]}</span>)}
        </div>
    )
}


const Translate = () => {
    return (
        <div style={{ display: 'flex', lineHeight: '160px', width: '600px', background: "#4787de", margin: '50px'}}>
            <TranslateProvider>
                <CnTranslate/>
                <EnTranslate/>
            </TranslateProvider>
        </div>
    )
}

export default Translate;
复制代码
相关文章
相关标签/搜索