[Sparta 개발 일지]_210604 3주차

최규빈·2021년 6월 5일
0

새로 알게된 것

  • React Router를 이용한 라우팅(Switch, Router 등)

  • Redux CreateStore로 Store 생성하기

  • Redux combineReducers로 여러 Reducer 하나로 묶기

  • 함수형 컴포넌트에서 Redux Store를 연결하는 방법(Provider)

  • 클래스형 컴포넌트에서 Redux Store를 연결하는 방법(Connect)

  • 함수형 컴포넌트에서 Redux를 이용한 전역 상태관리


React Router를 이용한 라우팅

  1. react-route-dom 설치
yarn add react-router-dom
  1. index.js에 import 및 컴포넌트 <BrowserRouter> 처리
    import { BrowserRouter } from "react-router-dom";
    ReactDOM.render() 내 컴포넌트들을 <BrowserRouter> 로 감싼다.

  2. return 부분에 <Route path="/"</Route> Route할 컴포넌트들 추가

  3. path가 지정되지 않은 비정상 접근 같은 경우 <Route></Route><Switch></Switch>로 감싸고 path prop이 없는 <Route></Route>를 추가하면 됨.

Redux CreateStore로 Store 생성하기 / Redux combineReducers로 여러 Reducer 하나로 묶기

아래 코드를 configStore.js 파일로 생성하되, src/redux/modules 디렉토리에 생성

import { createStore, combineReducers } from "redux";
import quiz from "./modules/quiz";
import rank from "./modules/rank";
import { createBrowserHistory } from "history";

export const history = createBrowserHistory();

const rootReducer = combineReducers({ quiz, rank });
const store = createStore(rootReducer);

export default store;

Redux Store를 프로젝트 컴포넌트에 연결하는 방법(Provider)

  1. 아래 코드를 index.js에 추가
// store를 컴포넌트에 연결해주는 역할
import { Provider } from "react-redux";

// 앞에서 생성한 store 불러오기
import store from "./redux/configStore";
  1. render() 부분에 모든 컴포넌트를 <Provider store={store}></Provider>로 감싼다.

클래스형 컴포넌트에서 Redux Store를 사용(Connect)

아래 코드를 Redux를 사용할 js파일에 추가

// 리덕스 스토어와 연결하기 위해 connect import
import {connect} from 'react-redux';

// 리덕스 모듈에서 (bucket 이라는 모듈을 가정) 액션 생성 함수 두개 import
import {loadBucket, createBucket} from './redux/modules/bucket';

// 스토어가 가진 상태값을 props로 받아오기 위한 함수
const mapStateToProps = (state) => ({
  bucket_list: state.bucket.list,
});

// 값을 변화시키기 위한 액션 생성 함수를 props로 받아오기 위한 함수
const mapDispatchToProps = (dispatch) => ({
  load: () => {
    dispatch(loadBucket());
  },
  create: (new_item) => {
    dispatch(createBucket(new_item));
  }
});

함수형 컴포넌트에서 Redux Store를 사용(useSelector, useDispatch)_간단 간단 초간단

아래 코드를 Redux를 사용할 js파일에 추가

// import
import {useSelector, useDispatch} from 'react-redux';

// configStore.js 파일에서 bucket이라는 이름으로 정의된(bucket이라는 js파일) 객체에서 list 객체 불러와서 bucket_list 변수에 저장
const bucket_list = useSelector(state => state.bucket.list);

함수형 컴포넌트에서 Redux를 이용한 전역 상태관리(bucketlist에서 bucket 삭제를 예시로)

Detail.js

import React from "react";

// redux hook 불러오기
import { useSelector, useDispatch } from "react-redux";
// 직접 생성한 버킷 삭제 액션 생성 함수 불러오기
import {deleteBucket} from "./redux/modules/bucket";

const Detail = (props) => {
  // useDispatch()는 이런 식으로 선언해주지 않고 직접 사용하면 오류 발생!
  const dispatch = useDispatch();
    
    
  // 스토어에서 상태값 가져오기
  const bucket_list = useSelector((state) => state.bucket.list);
  // url 파라미터에서 인덱스 가져오기
  let bucket_index = parseInt(props.match.params.index);

  console.log(props);
  return (
    <div>
      <h1>{bucket_list[bucket_index]}</h1>
      <button onClick={() => {
        dispatch(deleteBucket(bucket_index));
        props.history.goBack();
      }}>삭제하기</button>
    </div>
  );
};

export default Detail;

bucket.js: 액션, 액션 생성 함수, 리듀서가 있는 파일 (DELETE 키워드를 보면 됨)

// Actions
const LOAD = "bucket/LOAD";
const CREATE = "bucket/CREATE";
const DELETE = "bucket/DELETE";

const initialState = {
  list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
};

// Action Creators
export const loadBucket = (bucket) => {
  return { type: LOAD, bucket };
};

export const createBucket = (bucket) => {
  return { type: CREATE, bucket };
};

export const deleteBucket = (bucket) => {
  return { type: DELETE, bucket };
};

// Reducer
export default function reducer(state = initialState, action) {
    console.log(action);
  switch (action.type) {
    // do reducer stuff
    case "bucket/LOAD":
      return state;

    case "bucket/CREATE":
      console.log(state, action);
      const new_bucket_list = [...state.list, action.bucket];
      return { list: new_bucket_list };

    case "bucket/DELETE":
      const bucket_list = state.list.filter((l, idx) => {
        if(idx !== action.bucket){
            return l;
        }
      });
      return {list: bucket_list};

    default:
      return state;
  }
}

0개의 댓글