redux tool-kit을 추가해보자 feat(next js, typescript)

null·2021년 11월 21일
2

모듈 추가

npm i react-redux next-redux-wrapper @reduxjs/toolkit
npm i -D @types/react-redux typescript

slice 추가

module/slice/users.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
export interface User { 
  id: number;
  name: string;
}

//slice 안에 들어갈 내용은 name, init, reducers

//리덕스는 root reducer 객체를 가지고 있는데 이 객체의 key/ value쌍을 slice 라고 한다  요걸 업데이트 하는 reducer 함수가 slice reducer
//immer
export const usersSlice = createSlice({
  name: 'users',
  initialState: [
    { id: 1, name: '은지' }
  ] as User[],
  //reducer 안에 여러가지 함수가 들어갈 수 있음. 더하기 빼기 등등.. 그때마다 name 바꿔줄 필요 없음 
  reducers: {
    //액션타입은 슬라이스 이름을 접두어로 사용해서 자동 생성 >> 나같은 경우엔 users/addTodo
    addUser: (state, action: PayloadAction<User>) => {
      const { id, name } = action.payload;
      state.push({ id, name });
      // state.push(action.payload);
    },
  },
});

//위에 작성이 끝났다면 액션과 리듀서를 export 해준다. 
// export const { addUser } = users.actions;
// export default users.reducer;
const { actions, reducer } = usersSlice;
export const { addUser } = actions;

export default reducer;

store 작성

module/store.ts

import { configureStore } from '@reduxjs/toolkit';
import usersReducer from './slices/users';


const store = configureStore({
  reducer: {
    users: usersReducer,
  },
});

export default store;
export type RootState = ReturnType<typeof store.getState>;

store 연결

import React from 'react';
import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';
import store from './modules/store';

import { BrowserRouter } from 'react-router-dom';
import Routes from './containers/web/routes';

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <Routes />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

적용

import { useState, ChangeEvent, FormEvent } from 'react';

import Modal from '~/containers/web/components/modal';

import { RootState } from '~/modules/store';
import { User, addUser } from '~/modules/slices/users';

import { Wrap } from './styled';
import { useDispatch, useSelector } from 'react-redux';

function Mypage() {
  const [isOpen, setOpen] = useState(false);
  const [name, setName] = useState('');

  const users = useSelector<RootState, User[]>(state => state.users);
  const dispatch = useDispatch();
  
  function handle() {
    setOpen(prev => !prev); 
  }

  function handleChange(e: ChangeEvent<HTMLInputElement>) {
    setName(e.currentTarget.value);
  }

  function handleSubmit(e: FormEvent) {
    e.preventDefault();
    dispatch(addUser({ name } as User));
    setName('');
  }

  return (
    <>
      <p onClick={handle}>모달을 열어보자</p>
      {isOpen && (
        <Modal
          type="alert"
          handle={handle}
          title={<h1>잠깐만~</h1>}
        >
          <Wrap>
            <p>
              자유롭게 모달 내용을 작성한다
            </p>
          </Wrap>
        </Modal>
      )}

      <div>
        <form onSubmit={handleSubmit}>
          <input value={name} onChange={handleChange} />
          <button>추가</button>
        </form>

        {users.map((u: any) => (
          <div key={u.id}>{u.name}</div>
        ))}
      </div>

    </>
  );
}

export default Mypage;
profile
개발이 싫어.

0개의 댓글