MST

星途 面试题库

面试题:React中useReducer钩子的基本原理及中等应用

请阐述React中useReducer钩子与useState的区别。并举例说明在一个简单的计数器场景下,如何使用useReducer实现,同时展示如何处理复杂的状态更新逻辑,比如在计数器每次更新时,根据当前状态值的奇偶性执行不同的副作用操作。
39.3万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

区别

  1. 原理不同
    • useState 是一个简单的状态钩子,用于在函数组件中添加状态。它返回一个包含当前状态值和更新状态函数的数组。状态更新是通过直接传入新的值或使用回调函数形式来更新。
    • useReducer 是基于 Reducer 模式的状态钩子,类似于 Redux 中的 reducer。它接收一个 reducer 函数和初始状态作为参数。reducer 函数根据传入的 action 来决定如何更新状态。
  2. 适用场景不同
    • useState 适用于简单状态管理,当状态更新逻辑比较简单,直接设置新值就能满足需求时使用。例如管理一个布尔值的开关状态。
    • useReducer 适用于复杂状态管理,当状态更新逻辑依赖于当前状态,并且有多种不同的更新方式(由不同的 action 触发)时使用。例如购物车的添加、删除、修改商品数量等复杂操作。

使用 useReducer 实现简单计数器场景

import React, { useReducer } from'react';

// reducer 函数
const counterReducer = (state, action) => {
    switch (action.type) {
        case 'increment':
            return state + 1;
        case 'decrement':
            return state - 1;
        default:
            return state;
    }
};

const Counter = () => {
    const [count, dispatch] = useReducer(counterReducer, 0);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
        </div>
    );
};

export default Counter;

处理复杂状态更新逻辑(根据奇偶性执行不同副作用操作)

import React, { useReducer, useEffect } from'react';

// reducer 函数
const counterReducer = (state, action) => {
    switch (action.type) {
        case 'increment':
            return state + 1;
        case 'decrement':
            return state - 1;
        default:
            return state;
    }
};

const Counter = () => {
    const [count, dispatch] = useReducer(counterReducer, 0);

    useEffect(() => {
        if (count % 2 === 0) {
            console.log('The count is even, perform some even - related side effect');
        } else {
            console.log('The count is odd, perform some odd - related side effect');
        }
    }, [count]);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
        </div>
    );
};

export default Counter;