TIL 20211027 [항해99 42일차]

Arong·2021년 10월 26일
0

프로젝트 코드리뷰

목록 보기
2/12

메인페이지 카드리스트 만들기

1. 카드 앞면과 뒷면 뷰를 각각 먼저 만들어준다.

2. 데이터는 기본적으로 들어갈 default props를 지정해준다.

-> data.json이나 서버데이터를 받게되면 default props에서 데이터를 쓸일이 없어지긴 한다...

import React from 'react';
import PropTypes from 'prop-types';
import { Grid, Text } from '../elements';

// 전에는 (props)를 사용했지만 이제는 props 안에있는것을 전부 부르지 않고, 
// 필요한 값들만 넣어준다.  
const CardBack = ({ content, interest, stack }) => {
  return (
    <Grid
      width="960px"
      height="510px"
      borderRadius="16px"
      border="1px solid black"
    >
      <Grid>
        {/* <Image scr={image} shape="rectangle" /> */}
        <Text>{content}</Text>
        <Text>{stack}</Text>
        <Text>{interest}</Text>
      </Grid>
    </Grid>
  );
};

CardBack.propTypes = {
  content: PropTypes.string,
  // image: PropTypes.string,
  interest: PropTypes.string,
  stack: PropTypes.string,
};

CardBack.defaultProps = {
  content: '제 포트폴리오를 소개합니다.',
  // image:
  //   'https://mblogthumb-phinf.pstatic.net/MjAxNzA5MjdfODkg/MDAxNTA2NTIyOTMwOTA4.YSIpeIFX6GAna9UvWS_IarVWxfHYA4vHlC6Yn49YAQYg.f18IO5v8tMvIvbcv7bcdGRdoyW3QPK0gFbAAuhdCl4Mg.PNG.june6505/y1.png?type=w2',
  interest: '여행',
  stack: 'React',
};

export default CardBack;

EsLint를 사용하기 때문에 defaultProps들의 type들을 맞춰줘야한다.
yarn으로 prop-types를 설치해주고 각각 요소들의 PropTypes들을 지정해주기!!
타입 안맞으면 오류나니 주의하자😭

덕스 구조 만들기

  • type.js 파일에 따로 action만 모아서 만들어준다.
export const LOAD_CARD = 'LOAD_CARD';
export const CREATE_CARD = 'CREATE_CARD';
export const UPDATE_CARD = 'UPDATE_CARD';
export const DELETE_CARD = 'DELETE_CARD';
  • action.js 파일에 action creator함수와 미들웨어를 만들어준다.
import { createAction } from 'redux-actions';
import { apis } from '../../api/api';
import { LOAD_CARD, CREATE_CARD } from './types';

// Eslint는 카멜케이스로 쓰기!! _ 사용하면 오류남
export const loadCard = createAction(LOAD_CARD, (cardList) => ({
  cardList,
}));
export const createCard = createAction(CREATE_CARD, (card) => ({ card }));

export const loadCardDB = () => async (dispatch) => {
  try {
    const res = await apis.getCard();
    // console.log(res.data);
	
    // const { data } = res;는 구조할당분해이다. res에서 data만 가져오겠다는 의미.
    // 구조분해할당을 쓰면 loadCard(res)가 아닌 loadCard(data)를 해줘야한다.
    // const { data } = res;
    dispatch(loadCard(res.data));
  } catch (err) {
    console.log(err);
  }
};

res.data를 console로 찍어보면 0,1,2,3,4,5로 더이상에 객체는 없다.
리듀서에서 forEach는 객체일때 사용할 수 있기때문에 res.data 자체를 보내면 된다.
따로 여기서 구조할당분해를 해줄 필요는 없다.

  • reducer.js 파일에 reducer 함수들만 모아서 만들어준다.
/* eslint-disable */
import { handleActions } from 'redux-actions';
import { produce } from 'immer'; // reducer 불변성 유지
import { LOAD_CARD, CREATE_CARD, UPDATE_CARD, DELETE_CARD } from './types';

const initialState = {
  byId: {},
  allIds: [],
  current: {},
};

export default handleActions(
  {
    // immer를 이용한 불변성 유지! - produce 사용
    [LOAD_CARD]: (state, action) =>
      produce(state, (draft) => {
        // draft.byId = {};
        // draft.allIds = [];
        console.log(action.payload);
        //doc에 cardList에 담아온 리스트들이 담겨있다.
        action.payload.cardList.forEach((doc) => {
          draft.byId[doc.id] = doc;
          draft.allIds.push(doc.id);
        });
      }),

    [CREATE_CARD]: (state, action) => produce(state, (draft) => {}),
  },
  initialState,
);

draft.byId = {};와 draft.allIds = []; 생략해준 이유는 우리 로직에는 매번 새로고침을 할때 로드를 하기 때문에 굳이 초기화할 필요가 없다. 그치만 새로고침 안해도 로드를 해야할 일이 생기면 초기화 작업이 필요하다!

CardList 페이지에 리덕스에 저장된 데이터 불러오기

  • CardList.js
const CardList = () => {
  const dispatch = useDispatch();
  // const history = useHistory();
  //cardList변수에 state.cards에 저장한 리스트 정보들을 담아온다.(byId와 allIds가 담겨있음) 
  const cardList = useSelector((state) => state.cards);
	
  // useEffect는 미들웨어 데이터 콘솔로 확인하기 위해서 미들웨어 작업할때 먼저 만들어주기!
  React.useEffect(() => {
    if (cardList.allIds.length !== 0) {
      return;
    }

    dispatch(loadCardDB(String(0)));
  }, []);

  return (
    <Grid>
      <Div>
      // cardList안에 allIds에 저장된 id 인덱스 값들을 map으로 하나씩 부르기!
        {cardList.allIds.map((id) => {
     // CardFront component에 id값을 넘겨준다. id안에는 각 리스트들의 정보가 담겨있다.
          return <CardFront key={id} id={id} />;
        })}
      </Div>
    </Grid>
  );
};

export default CardList;
  • CardFront.js
const CardFront = ({ id = '' }) => {
  //front변수에 state에 저장한 cards에서 byId값 담기
  const front = useSelector((state) => state.cards.byId);
  return (
    <Grid
      width="350px"
      height="200px"
      borderRadius="16px"
      border="1px solid black"
    >
      <Div is_flex>
        <Image shape="circle" src={front[id].profile} />
        <Grid width="30%" margin="0px 20px">
          <Text>{front[id].userName}</Text>
          <Text>{front[id].stack}</Text>
          <Text>{front[id].interest}</Text>
        </Grid>
      </Div>
    </Grid>
  );
};

CardFront.propTypes = {
  id: PropTypes.number.isRequired,
};

const CardFront = ({ id = '' }) => {
  const front = useSelector((state) => state.cards.byId);
  return (
    <Grid
      width="350px"
      height="200px"
      borderRadius="16px"
      border="1px solid black"
    >
      <Div is_flex>
        <Image shape="circle" src={front[id].profile} />
        <Grid width="30%" margin="0px 20px">
          <Text>{front[id].userName}</Text>
          <Text>{front[id].stack}</Text>
          <Text>{front[id].interest}</Text>
        </Grid>
      </Div>
    </Grid>
  );
};

CardFront.propTypes = {
   // id는 index이기 때문에 type은 숫자인 number다.
  id: PropTypes.number.isRequired,
};

// 미들웨어를 통해 data.json 데이터를 가져와서 propTypse 오류 때문에 defaultProps는 생략했다. 
// CardFront.defaultProps = {
//   userName: '이아롱',
//   profile:
//     'http://file3.instiz.net/data/cached_img/upload/2019/12/09/17/c7dc4d6a28ec0d6079a6738c0e3fcc38.jpg',
//   interest: '여행',
//   stack: 'React',
// };

export default CardFront;

CardList.js에서 id={id}값을 준걸 사용해서 id안에 profile, userName, stack, interest 정보들이 담겨있는걸 사용한다! -> front[id].profile 이런식으로 데이터를 가져올 수 있다! (id는 인덱스이다!)



오늘은 새로운 리덕스 구조를 적용하면서 구조분해할당도 배우게 되고, byId, allIds에 대해서도 배우면서 새로운 지식이 늘게 되서 뿌듯하다.😊 그리고 오늘 적용한 propType맞추는게 꽤 귀찮은 작업이지만(생각보다 오류가 많이나서 힘들다..😭) 그래도 화이팅...!
profile
아롱의 개발일지

0개의 댓글

관련 채용 정보