패스트캠퍼스 메가바이트스쿨 Day 47 (10주차 목요일) - Redux 기초(2)

ctaaag·2022년 6월 24일
0
post-thumbnail

Redux 기초 (2)


Today Topic

✅ Redux-toolkit 개요
✅ 여러가지 state 관리(로그인)



1. Redux-toolkit 개요

🚀 Redux toolkit 장점

  • 우리는 react-redux라는 아주 고마운 존재가 있다고 저번 시간에 배웠지만, 이번엔 더 쉬운 놈을 들고 왔다. 바로 Redux toolkit이다.
  • createSlice로 여러가지의 state를 쉽게 만들어 관리가 가능하다
  • Slice에는 자동으로 state 객체를 복사해서 새로운 객체를 만든다. 그렇기 때문에 reducer함수로 직접 state 값을 변경을 해주더라도, 상관이 없다.

🚀 Redux toolkit에서 store 만들기

createSlice({
  name : "counter",
  initialState ,
  reducers:{
    increment(state){state.counter++},
    decrement(state){state.counter--},
    increase(state,action){state.counter+action.amount},
    toggleCounter(state){state.show=!state.show}
  }
});
  • 이전에 작성했던 카운터 함수를 이용했을 때보다 훨씬 짧아졌다. 우선 각각의 조건문을 모두 action으로 받아서 해당 action값일 때만 실행해주는 값이 달라야했던 때에 비해
  • redux-toolkit의 활용으로 함수로 선언을 해주니 각각의 상태값으로 행위를 분리할 필요가 없이 다른 함수를 호출하면 된다.
  • 그리고 redux에서 객체값을 복사하니 state값을 직접 바꿔주는 것처럼 작성해도 아무 문제가 없어지게 된다. magic!

🚀 Redux-toolkit에서 state호출하는 방법

const store = configureStore({
  reducer : counterSlice.reducer
});
const store = configureStore({
  reducer : {
    counter: counterSlice.reducer,
    addCounter : addCounterSlice.reducer,
  }
});
  • slice를 만들었다면 store를 정의하고, 불러와야함.
  • 이 때 사용하는 것이 configureStore임. configureStore의 가장 큰 장점은 여러 reducer를 한 번에 묶어서 관리가 가능하다는 것이다. 아래처럼 객체상태로 말이다.

🚀 Reducer 보내기

export const counterActions = counterSlice.actions;
import { counterActions } from "../store";

const incrementHandler = () => {
  dispatch(counterActions.increment())
}
const increaseHandler = () => {
  dispatch(counterActions.increase(5))
}
  • index.js의 store에서 진행하는 counterAction이라는 action을 전달하고 변수에 저장을 한다. 그럼 변수에는 각 reducer들이 자동으로 객체형태로 들어가게 된다.
  • 인자 값은 payload로 전달이 된다.

2. 여러가지 state 관리하기(Login)

이제는 login과 logout 상태를 관리해서 각 상태마다 다른 것들을 보여주고자 한다.

  • 로그아웃시 페이지

  • 로그인시 페이지

🚀 store 설계하기

const initialAuthState = { isAuthenticated: false }

const authSlice = createSlice({
  name : 'authentication',
  initialState: initialAuthState,
  reducers : {
    login(state){
      state.isAuthenticated=true;
    },
    logout(state){
      state.isAuthenticated=false;
    }
  }
});

export const authActions = authSlice.actions;
  • 위와 같이 기본 값을 false로 가지고 있는 state를 만들어주고, slice를 생성한다. 해당 slice의 이름과 기본 state값 설정, reducer 함수를 만들어서 해당 state가 바뀔 때 마다 값을 변경해주는 store를 만들었다.

🚀 App.js에서 state 변경해주기

function App() {
  const isLogin = useSelector(state => state.auth.isAuthenticated)

  return (
    <>
      <Header />
      {/* {!isLogin && <Auth/>}
      {isLogin && <UserProfile/>} */}
      {isLogin === false ? <Auth /> : <UserProfile/>}
      <Counter />
    </>

  );
}
  • 우선 App.js에서 각 상태마다 보여지는 것이 다르기 때문에 설정을 해줘야함
  • 삼항연산자를 사용할 수도 있고, &&를 이용해서 true를 충족시켰을 때 다른 페이지를 보여주는 형태로 작성해도 된다.

🚀Header.js에서 state 변경해주기

import { useDispatch, useSelector } from "react-redux";
import classes from './Header.module.css';
import { authActions } from "../store/auth";

const Header = () => {
  const dispatch = useDispatch()
  const isLogout = useSelector(state => state.auth.isAuthenticated)

  const handleLogout = () => {
    dispatch(authActions.logout())
  }
  return (
    <header className={classes.header}>
    <h1>Redux Auth</h1>
    <nav>
    { isLogout === false ? null : (
        <ul>
          <li>
            <a href='/'>My Products</a>
          </li>
          <li>
            <a href='/'>My Sales</a>
          </li>
          <li>
            <button onClick={handleLogout}>Logout</button>
          </li>
        </ul>
    )
}
    </nav>
    </header>
  )
  • 로그아웃 상태에서의 헤더의 특정 영역이 달라지기 때문에 위와 같이 header에서 설정해줘야한다.

🚀Auth.js에서 state 변경해주기

import { useDispatch, useSelector } from "react-redux";
import { authActions } from "../store/auth";
import classes from './Auth.module.css';

const Auth = () => {
  const dispatch = useDispatch()
  const isLogin = useSelector(state => state.auth.isAuthenticated)

  const handleLogin = () => {
    dispatch(authActions.login())
  }

  return (
    <main className={classes.auth}>
      <section>
        <form>
          <div className={classes.control}>
            <label htmlFor='email'>Email</label>
            <input type='email' id='email' />
          </div>
          <div className={classes.control}>
            <label htmlFor='password'>Password</label>
            <input type='password' id='password' />
          </div>
          <button onClick={handleLogin}>Login</button>
        </form>
      </section>
    </main>
  );
};

export default Auth;
  • 이 때 login button에 handler를 줬는데. 그렇게 되면 데이터 전송이 form을 통해서 되지 않으니까 form을 통해 handler를 통제하는것이 맞다. 따라서 아래와 같이 변경해서 코드를 작성할 수 있도록 하자
  • form을 다루는 방법을 아직 잘 모르니 추후 공부를 더 해볼 것!

🚀 form 수정

const Auth = () => {
  const dispatch = useDispatch()
  const isLogin = useSelector(state => state.auth.isAuthenticated)

  const handleLogin = (event) => {
    event.preventDefault();
    dispatch(authActions.login());
  }

  return (
    <main className={classes.auth}>
      <section>
        <form onSubmit={handleLogin}>
          <div className={classes.control}>
            <label htmlFor='email'>Email</label>
            <input type='email' id='email' />
          </div>
          <div className={classes.control}>
            <label htmlFor='password'>Password</label>
            <input type='password' id='password' />
          </div>
          <button>Login</button>
        </form>
      </section>
    </main>
  );
};

export default Auth;
profile
프로그래밍으로 지속가능한 세상을 꿈꾸며

0개의 댓글