其他API使用

57 阅读2分钟

useReducer

与useState类似,但是useReducer可以设置多个状态

import { useReducer } from 'react';
const setNum = (state, action) => {
    console.log(state, action);
    switch (action.type) {
        case 'add':
            return state + action.num;
        default:
            return state;
    }
}
const Book = () => {
    const [state, dispatch] = useReducer(setNum, 0);
    return (
        <div>
            <h1>Book</h1>
            <button onClick={() => dispatch({ type: 'add', num: 1 })}>+</button>
            <span>{state}</span>
            <button onClick={() => dispatch({ type: 'add', num: -1 })}>-</button>
        </div>
    )
}
export default Book;

useMemo、memo、useCallback

useMemo可以缓存函数,避免重复计算
使用场景:一些比较复杂运算的函数,避免重复计算,可以使用useMemo
// useMemo 是 React 的一个 Hook,它用于对复杂计算进行性能优化。当你有一个耗时的计算,而这个计算的结果在组件的多次渲染之间可以保持不变时,你可以使用 useMemo 来缓存这个计算的结果,从而避免在每次渲染时都重新执行这个计算。
// useMemo使用场景:一些计算量比较大的组件,每次渲染时都会进行计算,如果计算结果没有变化,则不需要重新渲染。
Memo组件:/Memo/index.js

useCallback:useCallback 用于缓存函数,避免父组件更新时,子组件重新渲染,作用于函数

import { useState, useMemo, useCallback } from 'react';
import MemoCom from './components/MemoCom';

const fib = (n) => {
    console.log('fib === ', n);
    if (n <= 3) {
        return n;
    }
    return fib(n - 1) + fib(n - 2);
}
const Memo = () => {
    const [count1, setCount1] = useState(0);
    const [count2, setCount2] = useState(0);
    const result = useMemo(() => fib(count1), [count1]);
    console.log('组件渲染 === ')
    const memoClick = useCallback((value) => {
        console.log('点击事件', value);
    }, [])
    return (
        <div>
            <h1>Memo</h1>
            <button onClick={() => setCount1(count1 + 1)}>count1:{count1}</button>
            <button onClick={() => setCount2(count2 + 1)}>count2:{count2}</button>
            <p>result:{result}</p>
            <div>
                <MemoCom count={count1} onMemoClick={memoClick} />
            </div>
        </div>
    )
}
export default Memo;

memo组件:MemoCom.js
// React.memo 组件优化
// 不使用memo时,父组件渲染时,子组件也会重新渲染
// 使用 memo函数,当props 发生变化时,才会重新渲染,
import { memo } from 'react';
const MemoCom = memo(({ count, onMemoClick }) => {
    console.log('MemoCom 渲染');
    const sonClick = () => {
        console.log('sonClick');
        onMemoClick(111)
    }
    return (
        <div>
            MemoCom
            <button onClick={sonClick}>点击</button>
        </div>
    )
});
export default MemoCom

forwardRef、useImperativeHandle

forwardRef:将父组件的ref传递给子组件
useImperativeHandle:将子组件的方法传递给父组件,让父组件可以调用子组件的方法,需要搭配forwardRef一起使用
父组件:/ForwardRef/index.js
// forwardRef
import { useRef } from 'react';
import SonCom from './components/SonCom';
const Forward = () => {
    const sonRef = useRef(null)
    const handleClick = () => {
        console.log(sonRef)
        // 这里是不使用useImperativeHandle,直接使用ref,可以获取到子组件用ref绑定的DOM元素
        // sonRef.current.focus()
        // 这里使用useImperativeHandle,将子组件的方法传递给父组件,让父组件可以调用子组件的方法
        sonRef.current.handleChange()
    }
    return (
        <div>
            <h1>Forward</h1>
            <SonCom ref={sonRef}/>
            <button onClick={handleClick}>点击</button>
        </div>
    )
}
export default Forward;
子组件:/ForwardRef/components/SonCom.js
import { forwardRef, useImperativeHandle, useState } from 'react';
const SonCom = forwardRef((props, bandRef) => {
    const [msg, setMsg] = useState('')
    const handleChange = () => {
        setMsg('父组件调用子组件的方法')
    }
    // 在这里将需要传递给父组件的方法,通过useImperativeHandle传递给父组件
    useImperativeHandle(bandRef, () => {
        return {
            handleChange,
            msg
        }
    })
    return (
        <div>
            <h1>SonCom</h1>
            <input value={msg} onInput={(e) => setMsg(e.target.value) } type='text' ref={bandRef} />
        </div>
    )
})
export default SonCom;