Redux (1)

Jtiiin:K·2023년 11월 9일
1
post-thumbnail

< Redux >

✅ Redux가 필요한 이유

✔ useState 의 불편함


1. 컴포넌트에서 컴포넌트로 State를 보내기위해서는 반드시 부-모 관계가 되어야 함
2. 조부모 컴포넌트에서 손자 컴포넌트로 값을 보내고자 할때도 반드시 부모 컴포넌트를 거쳐야만 함
(= 부모컴포넌트에서는 그 값이 필요가 없어도 단순히 손자 컴포넌트에게 전달하기 위해 불필요하게 거쳐야만 함 (조부모 → 부모 → 손자))
3. 자식 컴포넌트에서 부모 컴포넌트로 값을 보낼 수 없음

✔ Global state와 Local state

  • Local state (지역상태) 란?
    컴포넌트에서 useState를 이용해서 생성한 state
    좁은 범위 안에서 생성된 State 라고 생각하시면 됩니다.
  • Global state (전역상태)란?
    Global state는 컴포넌트에서 생성되지 않고 중앙화 된 특별한 곳에서 State들이 생성됨
    (= “중앙 state 관리소” )

👉 중앙 State관리소에서 State를 생성하고, 만약 어떤 컴포넌트에서 State가 필요하다면 컴포넌트가 어디에 위치하고 있든 상관없이 State를 불러와서 사용 할 수 있게 됩니다. 이렇게 특정 컴포넌트에 종속되어 있는 것이 아니라 “중앙 state 관리소”에서 생성된 State를 Global state라고 합니다. 그리고 이러한 값들을 관리하는 것을 전역 상태 관리 라고 합니다.


✅ Redux란?

중앙 state 관리소를 사용할 수 있게 도와주는 패키지(라이브러리)


✅ 사용방법

✔ 설치

yarn add redux react-redux
(react-redux는 react와 redux를 연결시켜주는 패키지)

✔ 폴더 구조

  • redux : redux 관련 파일 다 몰아넣기
  • config : redux 설정과 관련된 파일
  • configStore : “중앙 state 관리소"Store를 만드는 설정 코드들이 있는 파일
  • modules : 만들 State들의 그룹
    (todolist를 만든다면 그에 필요한 state이 모여있는 todos.js가 하나의 모듈이 되는데, 이런 모듈들이 모여 있는 파일)

✔ 설정코드

// configStore.js
import { createStore } from "redux";
import { combineReducers } from "redux";

/*
1. createStore()
리덕스의 가장 핵심이 되는 스토어를 만드는 메소드(함수) 입니다. 
리덕스는 단일 스토어로 모든 상태 트리를 관리한다고 설명해 드렸죠? 
리덕스를 사용할 시 creatorStore를 호출할 일은 한 번밖에 없을 거예요.
*/

/*
2. combineReducers()
리덕스는 action —> dispatch —> reducer 순으로 동작한다고 말씀드렸죠? 
이때 애플리케이션이 복잡해지게 되면 reducer 부분을 여러 개로 나눠야 하는 경우가 발생합니다. 
combineReducers은 여러 개의 독립적인 reducer의 반환 값을 하나의 상태 객체로 만들어줍니다.
*/

const rootReducer = combineReducers({}); 
const store = createStore(rootReducer); 

export default store; 
// index.js
// 원래부터 있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

// 우리가 추가할 코드
import store from "./redux/config/configStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(

	//App을 Provider로 감싸주고, configStore에서 export default 한 store를 넣어줍니다.
  <Provider store={store}> 
    <App />
  </Provider>
);

✔ 모듈 만들기

  • 초기값은 꼭 객체가 아니어도 되며, 배열, 원시값 등 자유롭게 넣을 수 있고, 객체에도 여러 개의 변수를 넣을 수 있음
  • 리듀서는 state를 action.type 에 따라 변경해주는 함수 (useState의 setState 역할)
// src/redux/modules/counter.js

// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서 == 변화를 일으키는 함수 
const counter = (state = initialState, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

✔ 모듈 스토어에 연결하기

// src/redux/config/configStore.js

// 원래 있던 코드
import { createStore } from "redux";
import { combineReducers } from "redux";

// 새롭게 추가한 부분
import counter from "../modules/counter";

const rootReducer = combineReducers({
  counter: counter, // <-- 새롭게 추가한 부분
});
const store = createStore(rootReducer);

export default store;

✅ 스토어와 모듈 연결 확인하기

✔ useSelector (=스토어 조회)

👉 컴포넌트에서 스토어를 조회할 때 react-redux에서 제공하는 useSelector 라는 훅 사용

// 1. store에서 꺼낸 값을 할당 할 변수를 선언합니다.
const number = 

// 2. useSelector()를 변수에 할당해줍니다.
const number = useSelector() 

// 3. useSelector의 인자에 화살표 함수를 넣어줍니다.
const number = useSelector( ()=>{} )

// 4. 화살표 함수의 인자에서 값을 꺼내 return 합니다. 
// 우리가 useSelector를 처음 사용해보는 것이니, state가 어떤 것인지 콘솔로 확인해볼까요?
const number = useSelector((state) => {
	console.log(state)
	return state
});
// src/App.js

import React from "react";
import { useSelector } from "react-redux"; // import 해주세요.

const App = () => {
  const counterStore = useSelector((state) => state); // 추가해주세요.
  console.log(counterStore); // 스토어를 조회해볼까요?

  return <div></div>;
}

export default App;

✔ 스토어에 있는 값을 사용하고 싶다면

const number = useSelector(state => state.counter.number); // 0
profile
호기심 많은 귀차니즘의 공부 일기

0개의 댓글