Redux - example

zzwwoonn·2022년 6월 8일
0

React

목록 보기
19/23

Redux 실습 코드 - Redux를 이용한 로그인, 로그아웃 예제

따로 파일을 만들어서 실습해보고 공부한 내용들 전부 긁어놓은 리액트 실습 페이지에다가 넣는 것까지 해보자

Profile.js

로그인 하기 전과 로그인 하고 난 후의 화면을 보여줄 컴포넌트

프로필 페이지에서 사용자 정보를 보여준다. 결론적으로는 스토어에 저장해놓은 State(데이터)들을 가져와서 여기다 뿌리는 것이다.

import React from 'react';
import { useSelector } from 'react-redux';

function Profile() {
	const user = useSelector(state => state.user.value);

	return (
		<div>
			<h1>Profile Page</h1>
			<p> Name : {user.name}</p>
			<p> Age : {user.age} </p>
			<p> Email : {user.email}</p>
		</div>
	);
}

export default Profile;

useSelector 를 이용하면 만들어놓은 리듀서에 접근할 수 있다.
(순서가 좀 뒤죽박죽이긴 하지만..)

리듀서에 뭐 많이 정의해놓을 수 있다고 했다 => 객체형식으로 되어 있음
리듀서에 있는 state에 접근할건데, 어느 state냐 하면 ? 아까 user라고 이름 지어준 리듀서에 있는 state에 접근할거란 말

그리고 user 리듀서에가 value로 초기값을 설정해놨다. 제일 처음엔

state => state.user.value

그 초기값들로 세팅을 해놓는다.

Store.js

Store를 식당으로 생각하면, 리듀서는 접시이다. 음식(데이터, 상태값)들을 줘야하는데 접시에 올려다 줄거다.

import React from 'react';
import { configureStore } from '@reduxjs/toolkit';
import userSlice from './User';

// 삭당에다가 접시 등록하기
export default configureStore({
	reducer: {
		user: userSlice,
	},
});

리덕스는 스토어에 모든 state 상태값(데이터)을 저장한다. 공식문서에서는 app폴더에 만들던데 어디다 만들던 사실 상관없다.
index.js에 만드는 사람도 있더라 => 이건 좀..;

configureStore라는 키워드 (=> 식당)가 reducer를 감싸고 있다. 저기서 모든 state를 관리한다.

이제 이 스토어를 연결시켜줘야 하는데 보통의 경우에는 index.js 에다가 연결해준다.

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

나는 index.js에서 뭔가를 해주는 게 뭔지 모르게 좀.. 불편해서 그냥 App.js에서 해줬다.

App.js

import Profile from './Components/Profile';
import Login from './Components/Login';
import { Provider } from 'react-redux';
import Store from './Redux/Store';

function App() {
	return (
		<Provider store={Store}>
			<div className="App">
				<Profile />
				<Login />
			</div>
		</Provider>
	);
}

export default App;

그리고 Provider 키워드로 App 전체를 감싸줘야 한다.

Provider 는?
store가 리액트 앱 전체를 감싸도록 해주는 역할이다. 공식문서에는 "Provider 는 react-redux 라이브러리에 내장되어있는, 리액트 앱에 store 를 손쉽게 연동 할 수 있도록 도와주는 컴포넌트입니다. 이 컴포넌트를 불러온다음에, 연동할 컴포넌트를 감싸준다음에 Provider 컴포넌트의 props로 store 값을 설정해주면 됩니다." 라고 나와있다.

User.js

이제 "접시" 즉, 리듀서를 만들어준다.

import { createSlice } from '@reduxjs/toolkit';

const initialStateValue = { name: '이름 초기값', age: 0, email: '이메일 초기값' };

const userSlice = createSlice({
	name: 'user',
	initialState: { value: initialStateValue },
	reducers: {
		login: (state, action) => {
			state.value = action.payload;
		},
		logout: state => {
			state.value = initialStateValue;
		},
	},
});

export const { login, logout } = userSlice.actions;
export default userSlice.reducer;

액션 객체를 받으면 전달받은 액션의 타입에 따라 어떻게 상태를 업데이트 해야 할지 정의를 해줘야한다. 이 때 업데이트 로직을 정의하는 함수를 리듀서라고 부른다. 이 함수는 나중에 우리가 직접 구현하게 된다. => login

예를 들어 type 이 INCREMENT 라는 액션이 들어오면 숫자를 더해주고,
DECREMENT 라는 액션이 들어오면 숫자를 감소시키는 그런 작업을 여기서 하면 된다.

리듀서 함수는 두가지의 파라미터를 받는다.

state: 현재 상태, action: 액션 객체

그리고, 이 두가지 파라미터를 참조하여, << 새로운 상태 객체를 만들어서 >> 이를 반환한다.

여기서 createSlice 라는 메서드를 쓴다. createSlice 는 기존에 createReducer와 createAction 이 하던 일을 같이 해준다. 쉽게 말해 actions를 위한 js파일을 따로 만들 필요가 없게 되는 것이다.

사용할 리듀서의 이름을 정하고(user), 그걸 createSlice로 지정해준다.

  • name 은 리듀서 이름 뭘로 할지 정하기

  • initialState 는 들어갈 데이터의 초기값 세팅하는 용도
    => 로그아웃할 때도(초기화) 똑같이 쓰이니 변수로 만들어놓고 재활용
    => initialStateValue

  • reducers 는 상태가 변하면 어떻게 로직을 실행하면 될 지 정하는 부분
    => 우리는 로그인 버튼을 눌렀을때 이름, 나이, 이메일이 변하게 하고 싶으니
    로그인 함수를 만들어준다. + 로그아웃

state는 우리가 잡아놓은 초기값의 value를 가져오는 역할을 하고, actions안에 payload랑 type 이 있는데 이는 우리가 바꾸고 싶은 데이터를 원하는 곳에다가 넘겨주는 역할을 한다.

순서가 좀 엉망이지만? 리듀서(접시)를 만들었으니 식당(스토어)에다가 등록하는 것이다.
=> Store.js

코드 제일 밑에 export 부분은

아까 만들어둔 login이라는 함수를 action 기능이 작동하도록 다른데서 쓸거라는 뜻이다.
=> "액션을 디스패치 하기 위함"

공식 문서에 나와있는 예제에서는 다음과 같다.

export const { increment, decrement, incrementByAmount } = counterSlice.actions

Login.js

import React from 'react';
import { useDispatch } from 'react-redux';
import { login, logout } from '../Redux/User';

function Login() {
	const dispatch = useDispatch();
	// action 을 보내는 역할, 디스패치를 날리는 역할

	return (
		<div>
			<button
				onClick={() => {
					dispatch(login({ name: '서지원', age: 25, email: 'zwon2056@gmail.com' }));
				}}
			>
				Login
			</button>
			<button
				onClick={() => {
					dispatch(logout());
				}}
			>
				Logout
			</button>
		</div>
	);
}

export default Login;

useDispatch 훅을 사용한다.
=> action을 보내는 역할이다 ("디스패치를 날린다"라고도 한다)

onClick 이벤트로 콜백 함수를 호출하는데 그 때 dispatch 가 사용된다.
=> 버튼을 클릭할 때마다 디스패치를 날린다
=> login을 날린다
=> login은 User에서 "다른 곳에서도 action 으로 작동 할 수 있도록" 만들어놨다 (바로 위에 User.js 에서 export 부분에 해당)

완성본

0개의 댓글