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
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
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
import { useRef } from 'react';
import SonCom from './components/SonCom';
const Forward = () => {
const sonRef = useRef(null)
const handleClick = () => {
console.log(sonRef)
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(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;