본문 바로가기
  • 삽질하는 자의 블로그
React/React-TypeScript

10. Redux-toolkit 과 함께 Typescript 사용하기 (2) 실전, useRef 를 이용해 받은 값, Redux Store 에 넣기

by 이게뭐당가 2022. 12. 27.

1. Todo-Slice 만들기

<store / todo-Slice.tsx>

        import { createSlice, PayloadAction } from "@reduxjs/toolkit";

        export type TodoType = {
            todos: { todoTitle: string; todoText: string }[];   // 타입 aliases
        };

        const initialState: TodoType = {
            todos: [{ todoTitle: "첫번째할일", todoText: "일어나기" }], // 초기값 설정
        };

        const TodoSlice = createSlice({
            name: "todos",
            initialState,
            reducers: {
                addTodo( state, action: PayloadAction<{ todoTitle: string; todoText: string }>  // PayloadAction 을 통해어떻게 입력될지 설정 
                ) {
                state.todos = [...state.todos, action.payload]; // action 함수 설정
                },
            },
        });

        export const TodoAction = TodoSlice.actions;

        export default TodoSlice.reducer;
        
** 타입 지정(state나 PayloadAction 에서)은, 일단 눈에 보이도록 해두었지만, "타입 별칭" 을 통해, "파일이나, 컴포넌트 내에서 미리 정의하여 아웃소싱하자"

 

 

2. 스토어에 등록한다.

<store / index.tsx>

    import { configureStore } from "@reduxjs/toolkit";
    import msSlice from "./ms-Slice";
    import todoSlice from "./todo-Slice";

    export const store = configureStore({
        reducer: {msSlice,todoSlice},       // 리듀서를 내보낸다.
    });

    export type RootState = ReturnType<typeof store.getState>;      // State 타입 설정 필수
    export type AppDispatch = typeof store.dispatch;                // 디스패치 타입 설정 필수

 

3. useRef와 함께 사용한다.

<components / NewTodo.tsx >

    import React from "react";
    import { useRef } from "react";
    import { useDispatch, useSelector } from "react-redux";
    import { TodoAction } from "../store/todo-Slice";       // Action import
    import { RootState } from "../store";                   // State 타입 import

    const NewTodo:React.FC = () => {
        const dispatch = useDispatch();
        const todoState = useSelector((state: RootState) => state.todoSlice.todos);
        const todoTitleRef = useRef<HTMLInputElement>(null);
        const todoTextRef = useRef<HTMLInputElement>(null);     // HTML input 의 타입, 초기값 지정(null)

        const todoSumbit = (event: React.FormEvent) => {        // event의 타입
            event.preventDefault();

            const todoTitle = todoTitleRef.current!.value;      // ! 로 바꿔 주어야, addTodo 에 넣을 수 있다.
            const todoText = todoTextRef.current!.value;        // ! 로 바꿔야, string 타입이 명확해지고,
                                                                //  Slice 를 만들때 분명 string 으로 action 이 들어올 것이라 명명했기 때문에
            dispatch(TodoAction.addTodo({ todoTitle, todoText }));
        };

        console.log(todoState);
        return (
            <div>
                <h1> 할일 넣기 </h1>
                <form onSubmit={todoSumbit}>
                    <div>
                        <label htmlFor="todoText"></label>
                        <input type={"text"} id={"todoText"} ref={todoTitleRef} />
                    </div>
                    <div>
                        <label htmlFor="todoText"></label>
                        <input type={"text"} id={"todoText"} ref={todoTextRef} />
                    </div>
                    <div>
                        <button> 제출 </button>
                    </div>
                </form>
            </div>
        );
    };

    export default NewTodo;

 

주의사항

useRef 와 같이, "있을수도, 없을수도" 있는 상태는, Type 이 확실하게 정해져있지 않다.

슬라이스를 만들때, "정확히" 타입을 지정했다면,

useRef 등을 사용할때 " ? " 가 아니라 " ! " 를 사용하여, 확실한 타입을 지정하자

댓글