[React] Redux / useSelector

안치영·2022년 10월 13일
1

React

목록 보기
8/15

🔥 Redux가 필요한 이유??

  • 컴포넌트에서 컴포넌트로 state를 보내기 위해서는 원래 반드시 props로 전달을 해야 하기 때문에, 부모 관계가 되어야 했다.

  • 조부모 컴포넌트에서 손자 컴포넌트로 값을 보내고자 할 때도 반드시 부모컴포넌트를 거쳐야만 한다. 즉 부모컴포넌트는 해당 값이 필요가 없어도 오로지 손자컴포넌트에 전달하기위해 불필요하게 거쳐야하는 것이다.
    이 현상을 Props Drilling 이라고 부른다

  • 자식 컴포넌트에서는 부모 컴포넌트로 state를 보낼 수 없다.

위와같은 이유로 React에서는 "전역 상태 관리 라이브러리"인

Redux 가 필요하다

이제부터는 Local state(컴포넌트 내 state), Global state(전역 state)를 구분해서 표현할 것이다.


🔥 Local State?

지역 상태라고 불리고, 컴포넌트에서 useState를 이용해서 생성한 state를 말한다. 즉 좁은 범위 안에서 생성된 state를 의미한다.

🔥 Gloabl State?

전역 상태라고 불리고, 컴포넌트에서 생성되지 않고, 중앙화된 특별한 곳에서 state들이 생성된다.

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


🔥 Redux 설정법

2개의 패키지를 설치해야 하는데,

  • yarn add redux react-redux

를 터미널에 치면 redux패키지 1개, react-redux패키지 1개 이렇게 2개의 패키지가 설치된다.

  • 폴더구조 생성하기
    • src폴더안에 redux폴더 생성
    • redux 폴더안에 config, modules 폴더 생성
    • config 폴더안에 configStore.js 파일 생성

파일명은 원하는대로 지어도 상관 없다.

용어 설명을 하자면,

redux : 리덕스와 관련된 코드를 모두 모아놓은 폴더
config : 리덕스 설정과 관련된 파일들만 놓을 폴더
configStore : 중앙 state 관리소인 store를 만드는 설정코드들이 있는 파일
modules : 우리가 만들 state 그룹


스토어 파일에는,

import { createStore } from "redux";
import { combineReducers } from "redux";

const rootReducer = combineReducers({//모듈명을 보통 쓴다.});
const store = createStore(rootReducer);

export default store;

index.js 파일에는,

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

import store from "./redux/config/configStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

이렇게 설정해주면 된다.


🔥 모듈 생성 및 연결

counter 모듈을 만든다고 예시를 지었을 때,
우리는 counter.js 파일을 만들어서 아래와 같이 작성한다.

// 초기 상태값
// const [number, setNumber] = useState(0) < 0에 해당하는 부분과 같은 이치
const initialState = {
  number: 0,
};

// 리듀서 : 변화를 일으키는 함수
// const onClickHandler = () => { setNumber(number+1)}
// state =  initialState 처럼 할당을 해줘야 한다.
// 두번째인자에서는 action이라는 것을 꺼내 사용한다.
const counter = (state = initialState, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

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

이게 모듈파일의 기본 구조이다.

그리고 스토어와 연결을 하기 위해서는,
스토어파일에서 연결을 해주어야 한다.

import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter"; // 추가

const rootReducer = combineReducers({
  counter: counter, // 추가 (모듈명)  counter만 작성해도 상관없다.
});
const store = createStore(rootReducer);

export default store;

이후, 연결이 됐는지 확인을 하려면 컴포넌트에서 스토어를 조회해야하는데,
이때 useSelector라는 react-redux의 Hook함수를 사용해야 한다.

🔥 useSelector로 연결 확인

일단 useSelector는 아래와 같은 과정으로 작성한다.

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

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

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

// 4. 화살표 함수의 인자에서 값을 꺼내 return 합니다. 
// state가 어떤 것인지 콘솔로 확인해보기
const number = useSelector((state) => {
	console.log(state)
	return state
});

이제 만들었던 스토어를 사용하면 된다.

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;

이렇게 조회를 해보면, 콘솔에는 객체가 찍히고, 그안에 counter라는 값을 볼 수 있다. 이것은 counter라는 모듈의 state가 보여지게 되는 것이다.

이렇게 화살표함수에서 꺼낸 state라는 인자는 현재 프로젝트에 존재하는 모든 리덕스 모듈의 state인 것이다.

컴포넌트에서 number라는 값을 사용하고자 한다면,

const number = useSelector(state => state.counter.number);

이런식으로 number값을 추출해낼 수 있다.

0개의 댓글