целесообразность useReducer в компоненте

Рейтинг: 0Ответов: 0Опубликовано: 13.04.2023

Решил поковырять useReducer, хотелось бы узнать, имеет ли место в моём компоненте хук useReducer, или же можно было обойтись обычным стейтом? Также, так как проект на TS, прошу указать на ошибки, которые "колют" глаза.

reducer.ts:

interface initState {
   width: number;
   height: number;
   isActive: boolean;
}

export const initialState: initState = {
   width: 350,
   height: 300,
   isActive: false,
}

export function reducer(state: initState, action: {type: string, payload: any}) {
   switch (action.type) {
       case "WIDTH":
         return {...state, width: action.payload}
       case "HEIGHT":
         return {...state, height: action.payload}
       case "IsACTIVE":
         return {...state, isActive: action.payload}
       default:
         return state
    }
}

AddTodoModal.tsx:

interface IAddTodoModal extends ITodoList {
    setShowModal: React.Dispatch<React.SetStateAction<boolean>>
}

const AddTodoModal: FC<IAddTodoModal> = (props) => {
const {todos, setTodos, setShowModal} = props

const [inputValue, setInputValue] = useState("")
const [state, dispatch] = useReducer(reducer, initialState)

function saveTodo(): void {
    setInputValue(inputValue)

    if (inputValue) {
        setTodos([...todos, {
            title: inputValue,
            sizes: [state.width, state.height],
            completed: false,
        }])
    }
    setShowModal(false)
}

function handleKeyDown(e: React.KeyboardEvent<HTMLTextAreaElement>) {
    if (e.key === "Enter") {
        e.preventDefault()
        saveTodo()
    }
}

function handleResize(e: any) {
    if (state.isActive) {
        dispatch({ type: "WIDTH", payload: e.clientX })
        dispatch({ type: "HEIGHT", payload: e.clientY })
    }
}

function suggestSize(w: number, h: number): void {
    dispatch({ type: "WIDTH", payload: w })
    dispatch({ type: "HEIGHT", payload: h })
}

return (
    <div className={"add-todo"}>
        <form
            onMouseMove={handleResize}
            onMouseUp={() => dispatch({ type: "IsACTIVE", payload: false })}
            action={"add todo"}
            style={{userSelect: state.isActive ? "none" : "auto"}}
        >
            <label htmlFor="input-field">Добавьте заметку</label>
            <div
                className={"container"}
                onMouseMove={handleResize}
                style={{width: `${state.width}px`, height: `${state.height}px`}}
            >
                <textarea
                    value={inputValue}
                    onChange={(e) => setInputValue(e.target.value)}
                    onKeyDown={handleKeyDown}
                    id="input-field"
                    placeholder={"Some text"}
                />
                <button
                    className="resizer"
                    onMouseDown={() => dispatch({ type: "IsACTIVE", payload: true })}
                >
                    <img src="/images/drag.png" alt=""/>
                </button>
            </div>
            <button className={"save"} type={"button"} onClick={() => {
                saveTodo()
            }}>Сохранить
            </button>
            <ul className="resize-panel">
                <li>
                    <button type={"button"} onClick={() => suggestSize(150, 150)}>150x150</button>
                </li>
                <li>
                    <button type={"button"} onClick={() => suggestSize(300, 300)}>300x300</button>
                </li>
                <li>
                    <button type={"button"} onClick={() => suggestSize(600, 600)}>600x600</button>
                </li>
            </ul>
        </form>
    </div>
);
};

Ответы

Ответов пока нет.