一般用于比较复杂的状态管理
- import { Button } from "antd";
-
- const { useReducer } = require("react");
-
- // 1. 定义reducer函数 根据不同的action 返回不同的状态
- function reducer(state, action) {
- switch (action.type) {
- case "INC":
- return state + 1;
- case "DEC":
- return state - 1;
- case "SET":
- return action.payload;
- default:
- return state;
- }
- }
-
- function App() {
- // 2. 组件中调用useReducer(reducer,0) => [state,dispatch]
- // reducer--reducer函数 0--状态初始值
- const [state, dispatch] = useReducer(reducer, 0);
-
- return (
- <div className="App">
- <Button type="primary" onClick={() => dispatch({ type: "DEC"})}>-Button>
- {state}
- {/* 3. 调用dispatch({type:'INC}) => 通知reducer产生一个新的状态 使用这个新状态更新UI */}
- <Button type="primary" onClick={() => dispatch({ type: "INC" })}>+Button>
- <Button type="primary" onClick={() => dispatch({ type: "SET", payload: 100 })}>updateButton>
-
- div>
- );
- }
-
- export default App;
在组件每次重新渲染的时候缓存计算的结果
- import { Button } from "antd";
- import { useMemo, useState } from "react";
-
- // 计算斐波那契数列之和
- function fib(n) {
- if (n < 3) return 1;
- return fib(n - 2) + fib(n - 1);
- }
-
- function App() {
-
- const [count1, setCount1] = useState(0)
- useMemo(() => {
- return fib(count1)
- })
-
- const [count2, setCount2] = useState(0)
-
- return (
- <div className="App">
- {result}
- <Button type="primary" onClick={() => setCount1(count1 + 1)}>测试{count1}Button>
- <Button type="primary" onClick={() => setCount2(count2 + 1)}>测试{count2}Button>
- div>
- );
- }
-
- export default App;
允许组件在Props没有改变的情况下跳过渲染-----解决父组件发生变化,子组件在没有的时候,不再重新渲染子组件
React组件的默认渲染机制:只要父组件重新渲染子组件就会重新渲染
- import { useMemo, useState } from "react";
-
- // 在使用memo缓存组件之后,React会对每一个 prop 使用 Objectis 比较新值和老值,返回true,表示没有变化
-
- const MemoSon = memo(function Son({count}) {
- console.log('子组件发生变化');
- return <div>son{count}div>;
- })
-
- function App() {
- // 1.简单类型
- const [count, setCount] = useState(0);
- // 2.引用类型 比较的是新值和旧值得应用 当父组件函数重新执行时,实际上形成的是新的数组引用
- // const list = [1, 2, 3]
- // 3.保证引用稳定
- useMemo(() => {
- return [1, 2, 3]
- }, [])
-
- return (
- <div className="App">
- <MemoSon count={list} />
- <button onClick={() => setCount(count + 1)}>+button>
- div>
- );
- }
-
- export default App;
在组件多次重新渲染的时候缓存函数
- import { useCallback, useState } from "react";
-
- const Input = memo(function Input({onChange}) {
- console.log('子组件发生变化');
- return <input type="text" onChange={(e) => onChange(e.target.value)} />
- })
-
- function App() {
- // 触发父组件重新渲染的函数
- const [count, setCount] = useState(0);
- // 穿给子组件的函数
- const changeHandler = useCallback((value) => console.log(value), []);
-
- return (
- <div className="App">
- <Input onChange={changeHandler} />
- <button onClick={() => setCount(count + 1)}>+button>
- div>
- );
- }
-
- export default App;
使ref暴露DOM节点给父组件
- import { forwardRef, useRef } from "react";
-
- const Input = forwardRef((props, ref) => {
- return <input type="text" ref={ref} />
- })
-
- function App() {
- const inputRef = useRef(null)
-
- const showRef = () => {
- console.log(inputRef);
- inputRef .current.focus();
- };
-
- return (
- <div className="App">
- <Input ref={inputRef} />
- <button onClick={showRef}>focusbutton>
- div>
- );
- }
-
- export default App;
使ref暴露DOM节点给父组件
- import { forwardRef, useRef, useInperativeHandle } from "react";
-
- const Input = forwardRef((props, ref) => {
-
- const inputRef = useRef(null)
- // 实现聚焦函数
- const focusHandler = () => {
- inputRef.current.focus()
- }
- // 暴露函数给父组件使用
- useInperativeHandle(ref, () => {
- return {
- focusHandler
- }
- })
- return <input type="text" ref={inputRef} />
- })
-
- function App() {
- const inputRef = useRef(null)
-
- const focusHandler = () => {
- inputRef.current.focusHandler();
- };
-
- return (
- <div className="App">
- <Input ref={inputRef} />
- <button onClick={focusHandler}>focusbutton>
- div>
- );
- }
-
- export default App;