TIL 20210927 [항해99 12일차]

Arong·2021년 9월 27일
0

App 컴포넌트에 있는 state를 리덕스로 교체해보기

  • 컴포넌트에서 리덕스 데이터 사용하기
    (1) 리덕스 훅
// useDispatch는 데이터를 업데이트할 때,
// useSelector는 데이터를 가져올 때 쓰며, ()안에 함수를 넣어줘야 한다!
import {useDispatch, useSelector} from "react-redux";

(2) 컴포넌트에서 redux데이터 가져오기
useSelector((state) ⇒ state.bucket)
configStore.js에서 루트 리듀서를 만들었는데, 여기에서 state는 리덕스 스토어가 가진 전체 데이터이다.
리덕스를 사용하기 전에는 컴포넌트에서 데이터를 가져왔다. 지금은 리덕스에 있는 데이터를 가져오는 방식으로 교체해보자.

...
// redux 훅 중, useSelector를 가져옵니다.
import { useSelector } from "react-redux";

//props는 App.js에서 주는 props이다. 
const BucketList = (props) => {
  let history = useHistory();
  //   이 부분은 주석처리!
  //   console.log(props);
  //   const my_lists = props.list; -> App.js에서 주는 props중에 list값
  // 여기에서 state는 리덕스 스토어가 가진 전체 데이터
  // 우리는 그 중, bucket(모듈폴더에 있는 js파일) 안에 들어있는 list를 가져온다. state를 리덕스로 대체한 코드임
  const my_lists = useSelector((state) => state.bucket.list); 
  //바로 위에 코드에서 (state) => 다음에 {}없으면 return되는 값이라는 의미
  return (
    <ListStyle>
      {my_lists.map((list, index) => {
        return (
          <ItemStyle
            className="list_item"
            key={index}
            onClick={() => {
              history.push("/detail");
            }}
          >
            {list}
          </ItemStyle>
        );
      })}
    </ListStyle>
  );
};
...

(3) 컴포넌트에서 redux 데이터 추가하기
-> import 부터!

// useDispatch를 가져온다!
import {useDispatch} from "react-redux";
// 액션생성함수도 가져오기!
import { createBucket } from "./redux/modules/bucket";

-> useDispatch 훅 쓰기

const dispatch = useDispatch();

const addBucketList = () => {
    // 스프레드 문법! 
    // 원본 배열 list에 새로운 요소를 추가해주었다.
    // setList는 state를 바꾸는 함수
    // 여긴 이제 주석처리!
    // setList([...list, text.current.value]);

	//text.current.value -> 새로 추가할 데이터(input에서 입력한 값)
    dispatch(createBucket(text.current.value));
  };

액션 생성함수는 액션을 리턴, 즉 액션을 만들어주기 때문에 매번 번거롭게 액션 객체를 써줄 필요가 없어진다.

URL 파라미터를 적용하기

(1) 몇번째 상세에 와있는 지 알기 위해, URL 파라미터를 적용하자

// App.js
//:index -> :파라미터명 
<Route exact path="/detail/:index" component={Detail} />
//BucketList.js
...
      {my_lists.map((list, index) => {
        return (
          <ItemStyle
            className="list_item"
            key={index}
            onClick={() => {
              // 클릭했을때 URL에 인덱스가 같이 붙어야 한다. +index로 붙이기
              history.push("/detail/"+index);
            }}
          >
            {list}
          </ItemStyle>
        );
      })}
...

(2) 상세페이지에서 버킷리스트 내용을 띄워보자

//Detail.js
// 리액트 패키지를 불러온다.
import React from "react";
// 라우터 훅을 불러오고, 이걸로 App.js에서 준 index라는 파라미터를 가져와야 한다.
import {useParams} from "react-router-dom";
// redux hook을 불러온다.
import { useSelector } from "react-redux";

const Detail = (props) => {
  // 스토어에서 상태값 가져오기
  const bucket_list = useSelector((state) => state.bucket.list);
  // url 파라미터에서 인덱스 가져오기
  const params = useParams();
  const bucket_index = params.index;

  return <h1>{bucket_list[bucket_index]}</h1>;
};

export default Detail;

리듀서

// 리듀서예요.
// 실질적으로 store에 들어가 있는 데이터를 변경하는 곳이죠!
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case "bucket/CREATE": {
        console.log("이제 값을 바꿀거야!");
        const new_bucket_list = [...state.list, action.bucket];
        return {list : new_bucket_list};
    }

    case "bucket/DELETE": {
      const new_bucket_list = state.list.filter((l, idx) => {
        return parseInt(action.bucket_index) !== idx;
      });
  	// 이 부분이 메인 리스트가 보여지는 곳!
    // 여기 return 뒤에는 state가 와야하기 때문에 딕셔너리 형태로 꼭 써주기!
     return {list: new_bucket_list};
    }
    default:
      return state;
  }
}

p.s. return parseInt(action.bucket_index) !== idx;
-> 이 부분은 !==은 '형'도 비교한다. 그래서 '형' 비교 안하게 하려면 '!='으로 사용하거나,
parseInt로 형변환을 해줘서 '형'을 맞춰주면 된다. 형변환을 해주는 방법을 추천!

액션을 디스패치 하는건 '나 이거 바꿔줘'하고 요청하는 것이다. 요청을 바꿔주는 건 리듀서에 있다. case로 요청들을 추가해주면 된다.


오늘은 2주차 개인 과제를 하면서 3일만에 리액트 기본강의를 훑어보느라 헷갈렸던 리덕스 부분을 다시 천천히 공부해보는 시간을 가졌다. 상태관리 흐름과 덕스 구조에 대해 감이 잡혀서 행복하다..!!

profile
아롱의 개발일지

0개의 댓글

관련 채용 정보