재사용 가능한 컴포넌트 레이아웃 분리하기(props)

이서우·2023년 3월 6일
0
post-thumbnail

🚨 문제 발생


잘못된 리덕스 사용

저번주에 API 데이터를 redux 대신 react-query 담아오도록 변경했다.

⇒ 이 과정에서 api데이터는 react-query로 가져오고 그중 현재 페이지 트윗데이터는 또 redux로 관리하였다.

⇒ react-query로 가져온 서버데이터를 또 redux에 담는것이 어색하고 불필요하게 느껴졌다.

⇒ redux에 담은 이유는 무한스크롤링에 따라 페이지가 변할때마다 현재 페이지 데이터를 변수에 담아서 트윗 박스에 보내주기 위함이었는데 이 데이터는 다른 곳에서 사용되는 것이 아니라 트윗 페이지에서만 사용되는 데이터이기때문에 store에서 전역변수로 관리될 필요가 없었다.

잘못된 컴포넌트 분리

또한 컴포넌트 파일로 분리한 tweetBox파일에서 데이터를 가져와서 관리하고 있었다.

⇒ 컴포넌트를 분리하는 이유는 그 레이아웃을 분리해서 재사용하기 위해서이다. 따라서 데이터를 그 컴포넌트 파일에서 관리할게 아니고 페이지 파일에서 props로 데이터를 넘겨줘서 로딩하고, 컴포넌트 파일에서는 컴포넌트 레이아웃만 사용하는것이 올바른 사용이다.

const { isLoading, isError, data, error } = useQuery(
    ["selectExploreData", pageCount],
    tweetFocusApi,
    {
      refetchOnWindowFocus: true, // react-query는 사용자가 사용하는 윈도우가 다른 곳을 갔다가 다시 화면으로 돌아오면 이 함수를 재실행합니다. 그 재실행 여부 옵션 입니다.
      retry: 0, // 실패시 재호출 몇번 할지

      onSuccess: (res: any) => {
        console.log(res.data.data);
        dispatch(changeCurrentPosts(res.data.data));
      },
      onError: (e: any) => {
        console.log(e.message);
      },
    }
  );

🙋🏻‍♀️ 해결과정


✅ 컴포넌트 레이아웃만 분리해서 사용하고 필요한 데이터는 페이지 파일에서 props로 넘겨주었다.

잘못 사용되고 있었던 컴포넌트 파일이 두개나 있었다.

  • tweetBox
  • searchBar

⇒ 둘다 레이아웃은 두고 데이터는 props로 받아쓰는걸로 수정하였다.

tweetBox컴포넌트

//explore 페이지
<TweetBox data={exploreData} />
//tweet 페이지
<TweetBox data={addData} />

const TweetBox = (prop: any) => {
  let data = prop.data;

/////

}

search컴포넌트

//explore페이지
<Searchbar onSearchbar={onExploreSearch} />
//message페이지
<Searchbar onSearchbar={peopleApi} />

const Searchbar = (onSearchbar: any) => {

const onSearch = (event: any) => {
    dispatch(changSearchState(search));
    event.preventDefault();

    onSearchbar.onSearchbar();
  };

<button
        type="submit"
        onClick={onSearch}
        className="p-2.5 ml-2 text-sm font-medium text-white bg-blue-300 rounded-lg hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600"
      >
<span className="sr-only">Search</span>
</button>

}

redux로 관리하던 데이터를 props로 넘겨주기 위한 과정에서 많은 에러들을 발견했다.

  • axios 요청보낼때 params 데이터 또는 focus 데이터가 업데이트가 안됨.

⇒ ✅ queryKey에 변수로 담아주니까 해결됨. queryKey가 업데이트가 되면서 각 변수값도 업데이트가 되어서 들어갈것이라고 예상했음. 그 전에는 쿼리키가 모두 무효화되어도 변경되어야하는 값들이 변수로 관리되어지지 않아서 똑같은 값으로 들어갔을거라고 추측.

데이터를 변경 하는 state가 있는 경우 Key가 변경 될 때 마다 React Query가 트리거 되어 자동으로 refetching하기 때문에 우리는 Key에 저장하기만 하면 된다. 필터를 적용하려면 state를 변경 시키면 된다.

//api요청 함수 
const tweetFocusApi = () => {
    return customAxios.get(`/getTweets/${focus}`, {
      params: { search, currentPage },

  const { isLoading, isError, data, error } = useQuery(
    //변경전 ["selectExploreData", pageCount],
		//변경후
    ["selectExploreData", currentPage, focus],
    tweetFocusApi,
    {
      refetchOnWindowFocus: true, // react-query는 사용자가 사용하는 윈도우가 다른 곳을 갔다가 다시 화면으로 돌아오면 이 함수를 재실행합니다. 그 재실행 여부 옵션 입니다.
      refetchOnWindowFocus: true,
      // react-query는 사용자가 사용하는 윈도우가 다른 곳을 갔다가 다시 화면으로 돌아오면 이 함수를 재실행합니다. 그 재실행 여부 옵션 입니다.
      retry: 0, // 실패시 재호출 몇번 할지
  • onSearch is not function 에러

기존의 코드는 onSearchbar()로 되어있었음.

const onSearch = (event: any) => {
    dispatch(changSearchState(search));
    event.preventDefault();

    onSearchbar();
  };

하지만 onSearchbar를 console.log를 찍어보니… 그 안에 또 오브젝트 형태로 onSearchbar 키 내가 실행하고자하는 함수 값으로 이루어져있었음.

따라서 onSearchbar.onSearchbar()로 바꿔서 해결.

아직 수정해야될 것들


  • 하트 버튼을 누르면 select로 시작하는 모든 쿼리가 무효화 되어서 새로 데이터를 가져오게 되는데 그때 api함수기능에 따라서 변경된 tweet이 담긴 페이지 데이터를 가져오는 것이 아니라, 현재 페이지에 해당되는 데이터를 가져옴
  • 또한 하트가 업데이트될때마다 데이터를 가져와서 데이터 배열에 추가됨. ⇒ 하트에 대한 데이터뿐만아니라 불필요한 데이터가 중복으로 담겨짐
  • people 데이터 type이 다른 데이터 배열 type과 다르기때문에 따로 처리해야함.

참고

[React] 컴포넌트에 Props 전달하기

[오류해결] Uncaught TypeError: is not a function

react onClick 파라미터 값 전달하는 방법

profile
프론트엔드 개발 지망생입니다:)

0개의 댓글