본문 바로가기
프로젝트/코드스테이츠 - 4주프로젝트

댓글버그수정, recoil로 비동기state사용

by 안뇽! 2021. 12. 7.
반응형

1. 댓글버그 수정

db의 내용을 미리 더미데이터로 만들어놓았다.



수정취소를 버튼을 누르면 다음과 같이 더미데이터의 값으로 변경되었다.

 

원인은 역시 이번에도 useState의 비동기로인한 렌더링순서 짬뽕이었다.

아래와 같이 렌더링순서를 꽉!! 잡아주니 모든것이 원래대로 돌아왔다.

 

 

2. 리코일로 비동기처리

2주프로젝트때 리덕스를 사용했음에도 리덕스 대신 리코일을 선택한이유는 비동기사용시 미들웨어를 추가학습할필요가 없어서였다.
프로젝트초기에 몇번시도해보았지만 너무어렵고 프로젝트는 공부하는때가 아니라 빨리 만들어야하는 때라고 생각해 우선 제껴두고 useEffect로 원래로 하던것처럼 만들었다. 오늘 시간이 좀 남아서 '카카오API를 통해 유저의 주소받는 axios'를 recoil의 selector함수로 만들었다.
주소값을 콘솔로그로 받는데는 성공했지만, 어떻게 '시군구 option 태그의 value'로 넣어야 하는지 방법을 알 수가 없었다.
useEffect를 안쓰려고 했지만, 쓸수밖에 없었다.(현재 내 시야에서는..)
맞는방법인진 모르겠지만 원하던대로 지도에 찍히는 pickpoint가 변경될때 시군구 선택창도 pickpoint와 일치하도록 변경되는 기능을 만들었다.

 

1. recoil.js

//recoil.js

// 지도를 클릭했을때 클릭한지점으로 좌표를 바꿔준다.
export const pickpoint = selector({
  key: "pickpoint",
  get: ({ get }) => {
    console.log(get(defaultposition).lat, get(defaultposition).lon);
    return [get(defaultposition).lat, get(defaultposition).lon];
  },
  set: ({ set }, arr) => {
    set(defaultposition, { lat: arr[0], lon: arr[1] });
  },
});

// 픽포인트셀렉터에 의해 변경된 defaultPosition의 좌표를 카카오API로 보내 주소값 반환
export const setLo = selector({
  key: "setLo",
  get: async ({ get }) => {
    return (
      axios
        .get(
          `https://dapi.kakao.com/v2/local/geo/coord2address.json?x=${get(pickpoint)[1]}&y=${
            get(pickpoint)[0]
          }&input_coord=WGS84`,
          { headers: { Authorization: `KakaoAK ${process.env.REACT_APP_REST_API}` } }
        )
        .then((res) => res.data.documents[0].address)
        .then((address) => {
          // console.log(address)
          console.log({
            area: address.region_1depth_name,
            sigg: address.region_2depth_name,
            address: address.address_name,
          });
          return { area: address.region_1depth_name, sigg: address.region_2depth_name, address: address.address_name };
        })
        //   .then(res=>console.log(meetingPlace))
        .catch((err) => console.log(err))
    ); //237줄에 console.log(meetingPlace)있음.
  },
});

 

2. 코드가 너무 길어서 써봤자 아무도 안읽을것같으니 요약하면

1. 지도를 클릭하면 setPickPoint([lat,lon])이 실행된다.
2. pickposition 셀렉터에 의해 위의 전역변수 defaultPosition이 바뀐다.
3. 위의 setLo에 의해 defaultPosition의 좌표를 주소값으로 반환한다

3. 컴퍼넌트 렌더링되는 곳

//리코일에서 비동기 쓸때 사용하는 라이브러리
import { ..., useRecoilValueLoadable } from "recoil"; 
const loc = useRecoilValueLoadable(setLo); 

.. ( 생략 ) ..

//이렇게 작성하면 loc가 작업중(아직 axios의 res가 반환되기 전)일때 
//<Loading /> 컴퍼넌트가 렌더링된다.
if (loc.state === "loading") { 
    console.log("로딩");
    return (
      <div>
        <Loading />
      </div>
    );
  }
  console.log(loc);

  // useEffect(()=>{

  // },[pickPoint])

//로딩이 끝나면 리렌더링된후 위의 if문을 건너뛰고 다음 리턴문을 렌더링한다.
  return (
    <div>
      <Styled.MapRightBar>
        <p>오늘 떠나볼 동네는?</p>

        <Styled.SearchWrapper>
          <Styled.SearchBar>
            <Styled.SearchLocation first value={area} onChange={(e) => changeArea(e.target.value)} name="h_area1">
              {cat1_name.map((el, idx) => {
                return <opti
반응형