새소식

기술 습관/React

[프로그래머스] 타입스크립트로 함께하는 웹 풀 사이클 개발 12-2

  • -

리덕스 Hooks 생성하기

  • 들어도 어려움.. 복습 필요
import { createSlice } from "@reduxjs/toolkit"; import { ITask } from "../../types"; type TModalState = { boardId: string; listId: string; task: ITask; }; const initialState: TModalState = { boardId: "board-0", listId: "list-0", task: { taskId: "task-0", taskName: "task 0", taskDescription: "task description", taskOwner: "hee", }, }; const modalSlice = createSlice({ name: "modal", initialState, reducers: { } }); export const modalReducer = modalSlice.reducer;
import { createSlice } from "@reduxjs/toolkit"; import { ILogItem } from '../../types' type loggerState = { logArray: ILogItem[] } const initialState: loggerState = { logArray: [] } const loggerSlice = createSlice({ name: 'logger', initialState, reducers: { } }) export const loggerReducer = loggerSlice.reducer;
import { createSlice } from "@reduxjs/toolkit"; import { IBoard } from "../../types"; type TBoardState = { modalActive: boolean; boardArray: IBoard[] } const initialState: TBoardState = { modalActive: false, boardArray: [ { boardId: 'board-0', boardName: '첫 번째 게시물', lists: [ { listId: 'list-0', listName: 'List 1', tasks: [ { taskId: 'task-0', taskName: 'Task 1', taskDescription: 'description', taskOwner: 'hee' }, { taskId: 'task-1', taskName: 'Task 2', taskDescription: 'description2', taskOwner: 'hee' } ] }, { listId: 'list-1', listName: 'List 2', tasks: [ { taskId: 'task-2', taskName: 'Task 3', taskDescription: 'description3', taskOwner: 'hee' }, ] } ] } ] } const boardSlice = createSlice({ name: 'boards', initialState, reducers: { } }) export const boardsReducer = boardSlice.reducer;
import { createSlice } from "@reduxjs/toolkit"; import { IBoard } from "../../types"; type TBoardState = { modalActive: boolean; boardArray: IBoard[] } const initialState: TBoardState = { modalActive: false, boardArray: [ { boardId: 'board-0', boardName: '첫 번째 게시물', lists: [ { listId: 'list-0', listName: 'List 1', tasks: [ { taskId: 'task-0', taskName: 'Task 1', taskDescription: 'description', taskOwner: 'hee' }, { taskId: 'task-1', taskName: 'Task 2', taskDescription: 'description2', taskOwner: 'hee' } ] }, { listId: 'list-1', listName: 'List 2', tasks: [ { taskId: 'task-2', taskName: 'Task 3', taskDescription: 'description3', taskOwner: 'hee' }, ] } ] } ] } const boardSlice = createSlice({ name: 'boards', initialState, reducers: { } }) export const boardsReducer = boardSlice.reducer;
// /store/index.ts // redux 사용할 때 redux store를 만들어줘야하는데 여기에서 만들게 됨 import { configureStore } from "@reduxjs/toolkit"; import reducer from "./reducer/reducer"; import { useSelector } from 'react-redux'; const store = configureStore({ reducer }); export type RootState = ReturnType<typeof store.getState> export type AppDispatch = typeof store.dispatch; // const logger = useSelector((state: RootState)=> state.logger); // 에러발생 /* chunk-EPSXJ6EN.js?v=a2c9f6bb:1062 Uncaught TypeError: Cannot read properties of null (reading 'useContext') at Object.useContext (chunk-EPSXJ6EN.js?v=a2c9f6bb:1062:29) at useReduxContext2 (react-redux.js?v=2b6e48a7:146:32) at useSelector2 (react-redux.js?v=2b6e48a7:184:9) at index.ts:13:16 React Hook "useSelector" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.eslintreact-hooks/rules-of-hooks */ export default store;
// /hooks/redux.ts // redux를 위한 hooks eg. useSelector => / useDispatcher => import { TypedUseSelectorHook, useSelector } from "react-redux"; import { useDispatch } from "react-redux"; import { AppDispatch, RootState } from "../store"; /** * TypedUseSelectorHook<RootState> 타입으로 정의해야하는 이유 * RootState로 값을 반환할 때 {state: {..RootState}} 형태로 만들어주기 위해 */ export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector export const useTypedDispatch = () => useDispatch<AppDispatch>(); // const logger = useTypedSelector(state => state.logger);
import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' import { Provider } from 'react-redux' import store from './store/index'; ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode> )
import { appContainer, board, bottons } from './App.css' function App() { return ( <div className={appContainer}> <div className={board}> test </div> <div className={bottons}> <button> 이 게시판 삭제하기 </button> <button> </button> </div> </div> ) } export default App
// vanilla-extract 이용 // - 원활한 사용을 위해 vite-config.ts에 vanillaExtractPlugin() 플러그인 추가 필수 import { createGlobalTheme, style } from "@vanilla-extract/css"; export const vars = createGlobalTheme("root", { color: { main: "#265cff", mainDarker: "#243f8f", mainFaded: "#cdd9ff", mainFadedBright: "#ebf0ff", list: "rgba(235, 236, 240, 0.5)", task: "#f1f1f1", taskHover: "#cdd9ff", brightText: "#212121", darkText: "#f1f1f1", secondaryDarkText: "#c8c8c8", secondaryDarkTextHover: "#d4d3d3", selectedTab: "rgb(137, 176, 174)", updateButton: "#4c7097", deleteButton: "#c04959", }, fontSizing: { T1: "32px", T2: "24px", T3: "18px", T4: "14px", P1: "12px", }, spacing: { sm: "4px", md: "8px", big1: "24px", big2: "16px", listSpacing: "32px", }, font: { body: "arial", }, shadow: { basic: "4px 4px 8px 0px rgba(34, 60, 80, 0.2)", }, minWidth: { list: "250px", }, }); export const appContainer = style({ display: "flex", flexDirection: "column", minHeight: "100vh", height: "max-content", width: "100vw", }); export const board = style({ display: "flex", flexDirection: "row", height: "100%", }); export const bottons = style({ marginTop: "auto", paddingLeft: vars.spacing.big2, });
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react(), vanillaExtractPlugin()], })

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.