티스토리 뷰

Frontend/React

[React] React Redux

AlgoRoot 2022. 3. 25. 03:19
반응형

 

퀴즈를 만들며 이해했다고 생각한 순간 내일 또 새로울 것 같아 늦은 시각이지만 오늘 한 부분을 되짚어보았다. 

확실히 글을 적으니 흐름을 이해하는데 더 도움이 된 것 같다. 

특히 reducer를 만드는 부분에서 action을 발동시키는 부분이 헷갈렸는데 적어보고, 실행해보니 이해가 되었다. 

아직 익숙하지는 않지만 이 부분은 많이 써보면 해결될 문제 같다. 

 

내일 읽어 볼 자료 : 리덕스는 왜 필요할까? 

 


Redux 

전역적으로 상태를 관리할 수 있는 라이브러리이다. 

리듀서는 순수한 함수여야 한다. (리덕스 규칙) (몰라)

 

상태관리흐름도 

아래는 기능별로 묶은 덕스(ducks) 구조를 따른 코드이다. 

 

1. State 

저장하고 있는 상태값("데이터") , 딕셔너리 형태 

const ADD_LIST = "quiz/ADD_LIST";

 

 

2. Action

상태에 변화가 필요할 때 발생, 객체이다.

{ type: ADD_LIST, user_list: user.list };

 

 

3. ActionCreator

액션객체를 리턴하는 액션 생성 함수. 

export const addList = (user.list) => {
  return { type: ADD_LIST, user.list: user.list };
};

 

 

4. Reducer

저장된 상태(data)를 변경하는 함수

// state = {}, action = {} state,action에 값이 안들어 온다면 빈 딕셔너리로 지정
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case "quiz/ADD_LIST": {
      const new_list = [
        ...state.list,
        action.user.list,
      ];
      console.log("reducer", new_list);
      return { ...state, list: new_list };
    }
    default:
      return state;
  }
}

 

- initialState 초기값을 지정해줄 수 있다.

그래서 리듀서에서 리턴할 때 값을 쌓아줄 수 있다. 

// 초기값 지정 
const initialState = {
  quiz_list: [
    { question: "Algoroot의 혈액형은 B형이다.", answer: false },
    { question: "Algoroot의 MBTI는 ENTJ이다..", answer: true },
    { question: "Algoroot는 자바스크립트를 사랑한다 💓", answer: true },
  ],
  user_answer_list: [],
};

 

5. Store

프로젝트에 리덕스를 적용하기 위해 만든다. 한 프로젝트에 한 개의 store만 쓴다. 

sotre에는 리듀서들과 옵션으로 필요한 것들을 묶어서 createSore에 넣어준다. 

그 리듀서들을 옵션으로 묶기위해 combineReducers를 import 해준다. 

import { createStore, combineReducers } from "redux";
import quiz from "./modules/quiz";
import user from "./modules/user";

// 리듀서들을 다 묶어주는 애
const rootReducer = combineReducers({ quiz, user });

// 필요한 옵션들이 있으면 묶어주는데 지금은 없으므로 바로 sotre를 만든다.
const store = createStore(rootReducer);

export default store;

 

 

6. dispatch

store의 내장함수. 액션을 발생시킬 때 쓴다. 

 

 

 

 


 

리덕스와 컴포넌트의 연결 

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter } from "react-router-dom";

// 리덕스와 컴포넌트를 연결해주는 Provider 
import { Provider } from "react-redux";
import store from "./redux/configStore";

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

 


 

컴포넌트에서 리덕스 데이터 사용

리덕스 훅 사용하기  : 다양한 리덕스 훅들 > 링크

 

- useSelector

데이터를 가져올 때 쓴다. 

 

- useDispatch

데이터를 업데이트 할 때 쓴다. 

useDispatch와 redux를 통해 생성한 액션 생성 함수를 Import 해서 적용시킨다.

 

 

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { addList } from "./redux/modules/quiz";

const Game = (props) => {
  const dispatch = useDispatch();

  const list = useSelector((state) => state.quiz.list);
  const user_list = useSelector((state) => state.quiz.list);
  
  // 액션함수를 발동시킨다. 
  const setAnswer = (user_list) => {
    dispatch(addAnswer(user_list));
  };

return (
      <div>
        <p>{list.length}번 문제</p>
        <h3>{quiz_list[user_list.length].question}</h3>
      </div>
  );
};

export default Quiz;

 

반응형