styled_components React Redux Netlify
과제 GitHub: https://github.com/NamgyungKim/wanted-codestates-project-3-8

과제: 충청북도 휴양림 중 마음에 드는 곳에 메모를 남겨 저장하는 서비스를 아래 조건에 맞춰 만들어주세요.

  • openAPI를 이용해 데이터 조회를 한다. (한번에10개씩 무한스크롤 구현)
  • 조회한 데이터에 메모를 작성할수 있도록한다.
  • 작성한 목록의 주소,메모,이름으로 검색이 가능하도록한다.
  • 메모는 로컬스토리지에 저장한다.

✨ 무한 스크롤

  • api로 불러온 데이터를 스크을 내릴 때마다 요청 하도록 했습니다.
  • Throttle을 이용해 이벤트 요청 횟수를 줄였습니다.
const throttle = (callback, delay) => {
    let timer = null;
    return arg => {
      if (timer === null) {
        timer = setTimeout(() => {
          callback(arg);
          timer = null;
        }, delay);
      }
    };
  };

const scroll = e => {
  if (document.body.offsetHeight < e.target.scrollTop + 700) {
    dispatch(getDataFromApi(pageCount));
    dispatch(getPageData(pageCount));
  }
};



✨ 검색 기능

  • 메모, 제목, 주소 원하는 항목을 선택해 검색할 수 있도록 구현 했습니다.
  • 타자를 입력할때마다 이벤트를 호출하는 것이 아닌, Debounce를 이용해 일정 시간이 지나면 검색이 되도록 했습니다.
// searchTheme = "메모" || "제목" || "주소" select
// searchContent = 검색text

const placeData = useSelector(state => ({
    placeData: state.placeData.placeItems,
  })).placeData.filter(item => item[searchTheme].includes(searchContent));



✨ 선택한 장소 저장기능

  • 요구사항에 맞춰서 로컬스토리지에 선택한 장소와 메모를 저장해놓고 이를 수정, 삭제하는 방법으로 CRUD를 구현했습니다.
  • 로컬스토리지에 데이터를 넣어준 후 store에 넣어주었습니다.
// utils/LocalStorage.js
const setItems = (key, value) =>
  localStorage.setItem(key, JSON.stringify(value));
const getItems = key => JSON.parse(localStorage.getItem(key));
const isExist = value => (value ? value : []);

export { setItems, getItems, isExist };
// action
export const savePlaceItem = item => {
  const placeItems = getItems('placeItems') || [];
  setItems('placeItems', [...placeItems, item]);
  return {
    type: SAVE_PLACE,
    payload: {
      item,
    },
  };
};

export const updatePlaceItem = (memo, index) => {
  const placeItems = getItems('placeItems').map((placeItem, i) => {
    return i === index ? { ...placeItem, message: memo } : placeItem;
  });
  setItems('placeItems', placeItems);
  return {
    type: UPDATE_PLACE,
    payload: {
      placeItems,
    },
  };
};

export const deletePlaceItem = removedIdx => {
  const placeItems = getItems('placeItems').filter(
    (_, idx) => idx !== removedIdx,
  );
  setItems('placeItems', placeItems);
  return {
    type: DELETE_PLACE,
    payload: {
      placeItems,
    },
  };
};



📚 배운점

  • Throttle에 대한 개념을 공부해볼 수 있었다. 이전에 Debounce와 무슨 차이가 있는지 모르겟다. callback 해주는것도 이전에 팀원분이 설명해주신거 듣기는 했지만 당시에도 잘 이해는 가지 않았다. -> 이후 다시 블로그에 정리해보고 직접 코드를 써보니 이해가 갔다. 이번에 codesandbox를 블로그에 넣어본건 처음인데 나중에 다시 찾아서 복붙하기에도 좋고, 작성하면서도 확실히 공부되는 느낌을 받았다.
    https://namgyungkim.github.io/javascript/Throttle,-Debounce/
  • 이번에 Redux를 사용했는데 솔직히 사용할 필요까지는 없었지만 연습삼아 다른 팀원분들이 구현해 두셨다. Redux까지는 겨우 이해할 수 있지만 thunk는 아직 뭔지 잘 모르겠다. 공부한 후에 다시 한 번 읽어봐야겠다.
  • API를 사용하면서 CORS에러가 나왔다. 처음에 그냥 package.json에 "proxy":"http://localhost:3000" 을 통해서 해결한 줄 알았으나, 배포할때 문제가 발생했다. 받은 API가 http여서 netlify 에서 배포가 안될줄 알았는데 그걸 우회하는 다른 방법이 있다고 한다. netlify.toml 에 리다이렉션설정을 해줄 수 있었다. 솔직히 이해는 잘 안간다. http-proxy-middleware가 동작하는 것도, 리다이렉션 해주는 것도..
    이건 나중에 공부를 따로 해봐야할 것 같다.
  • netlify에 배포는 잘됬으나, list에 들어가서 새로고침을 하면 PageNotFound가 떴다. from = "/*"를 해주니 해결되었다. SPA이라서 발생했던 문제인 것 같다.





Leave a comment