You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux Toolkit如何根据交互输入组件条件派发不同action

实现方案

不需要为三个时长字段单独写三个action,用一个通用更新action+给输入组件传入对应字段标识的方式就能实现,步骤如下:

1. 首先完善timerSlice的reducer逻辑

直接在reducers里加通用的时长更新、调整方法,通过payload传入要修改的字段名和目标值即可,Redux Toolkit支持直接修改状态字段,不用手动写不可变更新逻辑:

// timerSlice.js
import { createSlice } from '@reduxjs/toolkit'

const initialState = {
    pomodoroMinutes: 25,
    shortBreakMinutes: 5,
    longBreakMinutes: 15,
}

const timerSlice = createSlice({
    name: 'timer',
    initialState,
    reducers: {
        // 直接输入数值时的更新action
        updateMinutes: (state, action) => {
            const { field, value } = action.payload
            // 只允许修改已定义的三个时长字段,避免非法状态修改
            if (['pomodoroMinutes', 'shortBreakMinutes', 'longBreakMinutes'].includes(field)) {
                // 兜底处理,时长不能小于0
                state[field] = Math.max(0, Number(value))
            }
        },
        // 点击加减按钮时的调整action
        adjustMinutes: (state, action) => {
            const { field, delta } = action.payload
            if (['pomodoroMinutes', 'shortBreakMinutes', 'longBreakMinutes'].includes(field)) {
                const newValue = state[field] + delta
                state[field] = Math.max(0, newValue)
            }
        }
    }
})

// 导出action方法供组件调用
export const { updateMinutes, adjustMinutes } = timerSlice.actions
export default timerSlice.reducer

2. 改造NumberInput组件,补全交互所需props

原来的组件仅传入了label,现在需要补充值绑定、事件回调相关props,把加减按钮、输入框的交互事件都接上:

//NumberInput.js
import React from 'react';
import styled from "./NumberInput.module.css";

const NumberInput = ({ label, value, onIncrement, onDecrement, onChange }) => {
    return (
        <div className={styled.inputContainer}>
            <label htmlFor="">{label}</label>
            <input 
                className={styled.input} 
                type="number" 
                min={0}
                value={value}
                onChange={(e) => onChange(e.target.value)}
            />
            {/* 上箭头对应增加值 */}
            <button className={styled.inputBtn} type="button" onClick={onIncrement}>
                <svg width="14" height="7" viewBox="0 0 14 7" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M1 6L7 2L13 6" stroke="#1E213F" strokeOpacity="0.25" strokeWidth="2"/>
                </svg>
            </button>
            {/* 下箭头对应减少值 */}
            <button className={styled.inputBtn} type="button" onClick={onDecrement}>
                <svg width="14" height="7" viewBox="0 0 14 7" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M1 1L7 5L13 1" stroke="#1E213F" strokeOpacity="0.25" strokeWidth="2"/>
                </svg>
            </button>
        </div>
    );
};

export default NumberInput;

3. 在弹窗父组件中传入对应配置使用

从store读取三个时长的值,给每个NumberInput传入对应字段的操作回调即可,不需要重复写多套dispatch逻辑:

// 设置弹窗组件示例
import { useDispatch, useSelector } from 'react-redux'
import NumberInput from './NumberInput'
import { updateMinutes, adjustMinutes } from './timerSlice'

const SettingsModal = () => {
    const dispatch = useDispatch()
    // 从store读取三个时长的当前值
    const { pomodoroMinutes, shortBreakMinutes, longBreakMinutes } = useSelector(state => state.timer)

    // 抽成配置数组,不用重复写三次组件代码
    const inputConfig = [
        { label: '番茄工作时段', field: 'pomodoroMinutes', value: pomodoroMinutes },
        { label: '长休息时段', field: 'longBreakMinutes', value: longBreakMinutes },
        { label: '短休息时段', field: 'shortBreakMinutes', value: shortBreakMinutes },
    ]

    return (
        <div className="modal">
            {inputConfig.map(item => (
                <NumberInput
                    key={item.field}
                    label={item.label}
                    value={item.value}
                    onIncrement={() => dispatch(adjustMinutes({ field: item.field, delta: 1 }))}
                    onDecrement={() => dispatch(adjustMinutes({ field: item.field, delta: -1 }))}
                    onChange={(val) => dispatch(updateMinutes({ field: item.field, value: val }))}
                />
            ))}
        </div>
    )
}

export default SettingsModal

这种实现方式比写三个独立action更易维护,如果后续要新增时长类型,只需要在initialState和配置数组里加对应项即可,不用重复编写reducer和组件逻辑。

内容的提问来源于stack exchange,提问作者Dastan Zhamekeshev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:48:34