简体   繁体   中英

Conditionally dispatching actions in Redux Toolkit

I am working on my pomodoro timer using Redux Toolkit.

I am supposed to have three inputs where I can customize the number of minutes for pomodoro period (1), long (2) and short breaks (3).

Therefore, I created <Input/> component and rendered it 3 times in the popup.

//NumberInput.js

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

const NumberInput = ({label}) => {
    return (
        <div className={styled.inputContainer}>
            <label htmlFor="">{label}</label>
            <input className={styled.input} type="number" min={0}/>
            <button className={styled.inputBtn} type="button">
                <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">
                <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;

And I have timerSlice.js where I keep my time data:

import { createSlice } from '@reduxjs/toolkit'

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

const timerSlice = createSlice({
    name: 'timer',
    initialState,
    reducers: {}
})

export default timerSlice.reducer;

The problem is that I can't guess how to dispatch different actions depending on the input user interacts with. For example, if I try to increment/decrement long break minutes I need to dispatch one action to change my longBreakMinutes field in the slice; in case of shortBreakMinutes another action.

You can create an array to distinguish between the inputs and dispatch actions by identifying the input by value to save those changes.

const ParentComponent = () => {
const minuteType = ['long', 'short']; 

minuteType.map((type, idx) =>  {
    return <NumberInput type={type} key={idx}/>
})
}

const NumberInput = ({label, type}) => {
const [inputVal, setInputVal] = useState('');
const dispatch = useDispatch(); 

const saveChanges = () => {
    if (type === 'long') {
        dispatch(saveLongMinutes(inputVal))
    }
    if (type === 'short') { 
        dispatch(saveShortMinutes(inputVal))
    }
}

return (
 
    {/* Other Content */}
        <input className={styled.input} type="number" min={0} onChange={(event) => setInputVal(event.target.value)}/>
        <button type="button" onclick={saveChanges}>
        Save
    </button>
);

};

Redux Store

const timerSlice = createSlice({
name: 'timer',
initialState,
reducers: {
    saveLongMinutes(state, action) {
        state.longBreakMinutes = action.payload
    }, 
    saveShortMinutes(state, action) {
        state.shortBreakMinutes = action.payload
    }  
}
})
export const { saveLongMinutes, saveShortMinutes } = timerSlice.actions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM