React Hook学习篇 - useReducer

本文介绍了在React组件中,当需要管理多个紧密关联的state时,如何使用useReducer来提高代码组织和性能。通过一个具体的Read组件例子,展示了如何定义reducer函数处理不同的状态更新,以及如何通过dispatch来更新状态,同时对比了useReducer与useState在复杂状态管理场景下的优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

useReducer是useState的升级版
背景说明:
当我们在一个组件中需要设置多个state,但是多个state的关联特别的密切,比如说,当组件中存在非常的类型,日期类型,具体日期,爱好,主类别,子类别…(假设关系非常紧密,用的时候几乎都是一起拿到)
如果说明分别使用state,需要非常多的state,别人找时非常容易混乱,如果直接使用useReducer便会方便很多。

useReducer语法

const [state, dispatch] = useReducer(reducer, initialArg, init);

官网说明

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)

在某些场景下,useReducer会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数 。

Read/index.jsx父组件

import React, { useState, useReducer } from 'react';
import List from './components/List';
import Card from './components/Card';
import Segment from '../../components/Segment';
import { CLASSIFY, DATE_TYPE } from '../../util/constant';
import './index.scss';

const getItem = (state, action) => {
    console.log('gettt', state, action);
    switch (action?.type) {
        case 'seg1':
            return {
                ...state,
                segText1: action?.data?.text,
                segVal1: action?.data?.value,
            }
        case 'seg2':
            return {
                ...state,
                segText2: action?.data?.text,
                segVal2: action?.data?.value,
            }
    }
}
const initState = {
    segText1: '',
    segVal1: '',
    segText2: '',
    segVal2: ''
}
function Read(pros) {
    console.log('redner-read');

    const [list1, setList1] = useState(0);
    const [card1, setCard1] = useState(0);
    const [card2, setCard2] = useState(0);

    const [state, dispatch] = useReducer(getItem, initState)

    const cardGetCount1 = (value) => {
        setCard1(value)
    }
    const cardGetCount2 = (value) => {
        setCard2(value)
    }
    const listGetCount1 = (value) => {
        setList1(value)
    }
    const getSeg1 = (item) => {
        dispatch({ type: 'seg1', data: item })
    }
    const getSeg2 = (item) => {
        dispatch({ type: 'seg2', data: item })
    }
    console.log('segment', state);
    return (
        <>
            <div className='top_READ'>
                <h2> Read</h2>
                <div>
                    <Segment
                        option={CLASSIFY}
                        onChange={getSeg1}
                    />
                    <Segment
                        option={DATE_TYPE}
                        onChange={getSeg2}
                    />
                </div>
                <List
                    value1={list1}
                    listGetCount1={listGetCount1}
                />
                <br />
                <Card
                    value1={card1}
                    value2={card2}
                    cardGetCount1={cardGetCount1}
                    cardGetCount2={cardGetCount2}
                />
            </div>
        </>
    )
}
export default Read;

Segment/index.jsx子组件

import React, { useState } from "react";
import './index.scss';

export default function Segment(props) {
    const {
        option = [],
        value,
        onChange,
    } = props;

    // 当option为[],不执行
    const [val, setVal] = useState(value || option?.length ? option[0]?.value : '');

    const handleItem = (item) => {
        return () => {
            setVal(item?.value);
            onChange(item)
        }
    }

    if (!option?.length) {
        return null;
    }
    console.log('render--Segment',);
    return (
        <div className="segment">
            {
                option?.map((v, index) => {
                    return (
                        <button
                            key={v?.text + index}
                            className={`item ${val === v?.value ? 'activeItem active' : ''}`}
                            onClick={handleItem(v)}
                        >
                            {v?.text}
                        </button>
                    )
                })
            }
        </div>
    )
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值