본문 바로가기

공부일지/React

비전공자의 공부일지 - Redux, Reducer, Provider, reduxToolkit

728x90
반응형
반응형

 

 

Redux


  • Props

 

  1. properties의 줄임말이다.
  2. Props는 구성 요소가 서로 통신하는 방법이다.
  3. Props는 상위 구성 요소에서 아래쪽으로 흐른다.
  4. 해당 값을 변경하려면 자식 관점에서 Props를 변경할 수 있으며, 부모는 내부 상태를 변경해야 한다.
  • State
  1. 부모 컴포넌트에서 자식 컴포넌트로 data를 보내는 게 아닌 해당 컴포넌트 안에서 data를 전달할 때 사용
  2. 예를 들어서 검색 창에 글을 입력할 때 글이 변하는 것은 state로 변경
  3. State is mutable = 조작 가능하다는 뜻이다.
  4. State가 변하면 re-render 된다.

※ 출처 : 패스트캠퍼스 (프론트엔드 웹 개발의 모든 것 초격차 패키지 Online)

 

리덕스 공식 홈페이지

https://ko.redux.js.org/

 

Redux - 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너. | Redux

자바스크립트 앱을 위한 예측 가능한 상태 컨테이너.

ko.redux.js.org

 

 

Redux는 State를 관리한다.

우리가 Redux를 사용 전에는 우리가 어떤 액션을 주면 바뀐 데이터를 부모컴포넌트까지 보내는 작업을 다 만들어야 하지만 Redux를 사용하면 *Action을 요청하고 그게 *Reducer를 통해서 *Redux Store에서 switch case문을 통해 State를 변경한다고 한다. 

 

Action

Action은 JavaScript 객체이다.

작업의 유형을 지정하는 type 속성이 있으며 선택적으로 redux 저장소 일부 데이터를 보내는 데 사용되는 payload 속성을 가질 수도 있다.

{type: 'LIKE_ARTICLE', articleid:42}
{type: 'FETCH_USER_SUCCESS', response: {id:3, name:'Mary'}}
{type: 'ADD_TODO', text: 'Read the Redux docs'}

이런 Action을 Reducer로 전달한다.

 

Reducer

쉽게 생각하면 상태의 변경 사항을 결정하고 업데이트된 상태를 반환하는 함수이다. 

Store의 내부 상태를 업데이트한다.

 

to change something into a simpler or more general form

 

무언가를 더 단순하거나 더 일반적인 형태로 바꾸는 것이라는 뜻이 있다고 한다.

 

작업할 때 State를 변경해야 될 때 그에 알맞은 상태로 변경되게 하는 작업이 Reducer라고 한다. 

즉, 리덕스에서의 reduce()는 현재상태(previousState)를 새로운 상태(newState)로 변경할 때 쓰는 함수이다.

 

리덕스 공식홈페이지에서의 설명은
"여러분이 이 형태의 함수를 Array.prototype.reduce(reducer,? initialValue)로 넘길 것이기 때문에 리듀서라고 부릅니다"

다시 말해, 리듀서라고 불리는 이유는 리듀서가 reduce() 함수에서 사용하는 콜백함수이기 때문에 리듀서라고 불립니다.

 

※ 참고한 사이트

https://devlog.jwgo.kr/2018/08/23/redux-which-is-weird-term/

 

리듀서(Reducer)가 뭔가요? · Tonic

사이트 운영에 도움을 주실 수 있습니다. 고맙습니다. --> 리듀서(Reducer)가 뭔가요? 2018년 08월 23일 리액트(React)와 리덕스(Redux)를 보다 보면 반드시 만나는 단어가 리듀서(Reducer)다. 근데 이게 정말

devlog.jwgo.kr

 

Redex Store

앱의 전체 상태 트리를 가지고 있는 저장소입니다. 이 안의 상태를 바꾸는 유일한 방법은 여기에 액션을 보내는 것뿐입니다.

저장소는 클래스가 아닙니다. 단지 안에 몇 가지 메서드가 들어있는 객체일 뿐입니다. 생성하기 위해서는 루트 리듀싱 함수 createStore에 전달하면 됩니다.

 

https://ko.redux.js.org/api/store/

 

Store | Redux

API > Store: the core Redux store methods

ko.redux.js.org

 

Redux에서 store은 하나 밖에 만들지 못하지만

import { combineReducers } from "redux";
import counter from "./counter";
import todos from "./todos";

const rootReducer = combineReducers({
  todos,
  counter,
});

이런 식으로 todos의 store와 counter라는 store을 만들어 대표 store에 넣어서 사용 가능하다.

 

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { createStore } from "redux";
import rootReducer from "./reducers";

const store = createStore(rootReducer);

store.dispatch({
  type: "ADD_TODO",
  text: "USE_REDUX",
});

console.log(store.getState())
const rootElement = document.getElementById("root")!;
const root = ReactDOM.createRoot(rootElement);

const render = () =>
  root.render(
    <React.StrictMode>
      <App
        value={store.getState()}
        onIncrement={() => store.dispatch({ type: "INCREMENT" })}
        onDecrement={() => store.dispatch({ type: "DECREMENT" })}
      />
    </React.StrictMode>
  );
render();
store.subscribe(render);

 

index.tsx의 코드 화면이다.

 

Redux Provider

어제 공부했던 ReactContext의 Provider와 비슷한 거 같다.

이거 또한 컴포넌트가 많아지고 하나의 state를 다양한 컴포넌트에서 사용할 때가 있는데 그럴 때 사용한다.

 

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { createStore } from "redux";
import rootReducer from "./reducers";
import { Provider } from "react-redux";

const store = createStore(rootReducer);

store.dispatch({
  type: "ADD_TODO",
  text: "USE_REDUX",
});

console.log(store.getState());
const rootElement = document.getElementById("root")!;
const root = ReactDOM.createRoot(rootElement);

const render = () =>
  root.render(
    <React.StrictMode>
      <Provider store={store}>
        <App
          value={store.getState()}
          onIncrement={() => store.dispatch({ type: "INCREMENT" })}
          onDecrement={() => store.dispatch({ type: "DECREMENT" })}
        />
      </Provider>
    </React.StrictMode>
  );
render();
store.subscribe(render);

위에서 보았던 코드와 비슷하지만 이번에는 Provider 컴포넌트로 App 컴포넌트를 감쌌다.

Provider을 사용하기 위해서는 store라는 속성을 넣어 주어야 한다.

나는 store에 넣어야 될 값도 store로 만들어서 store={store}을 넣어주었다.

 

  • useSelector

redux store에서 값을 가져올 수 있다.

 

  • useDispatch

selector을 이용해서 가져온 값을 다시 store에 보낸다.

 

 

Redux MiddleWare

리덕스 미들웨어는 Action을 dispatch 하고 리듀서에 도달하기 전에 지정한 작업을 진행하는 중간자이다.

로깅, 충돌보고, 비동기 API와 통신, 라우팅 등을 위해 사용한다.

 

  useEffect(() => {
    dispatch(fetchPosts());
  }, [dispatch]);

  const fetchPosts = (): any => {
    return async function fetchPostsThunk(dispatch: any, getState: any) {
      const response = await axios.get(
        "https://jsonplaceholder.typicode.com/posts"
      );
      dispatch({ type: "FETCH_POSTS", payload: response.data });
    };
  };

 

자세한 내용은 아래의 codesandbox를 참고하면 될 거 같다.

 

 

 

리덕스는 가볍게 테스트 같은 느낌으로 작업 중이라

https://codesandbox.io/p/sandbox/reduxtest-fo79vu

 

reduxTest

CodeSandbox is an online editor tailored for web applications.

codesandbox.io

codesandbox에서 작업 중이다.

 

 

728x90
반응형