React 이런저런 끄적임

이수빈·2023년 9월 5일
0

React

목록 보기
3/20
post-thumbnail

Browser Router 직접 설정가능

  • 중첩라우팅, Suspense, lazy Loading을 각각의 컴포넌트별로 적용가능하다.

  • children으로 todoRouter를 정의함.

  • 이런식으로 라우팅을 정의하면 => 페이지가 많아졌을때 라우터 설정하는게 효과적임

//root.js
import { Suspense, lazy } from "react";
import todoRouter from "./todoRouter";
const { createBrowserRouter } = require("react-router-dom");
 
const Loading = <div>Loading....</div>
const About = lazy(() => import("../pages/AboutPage"))
const Main = lazy(() => import("../pages/MainPage"))

const TodoIndex = lazy(() => import("../pages/todo/IndexPage"))

const TodoList =  lazy(() => import("../pages/todo/ListPage"))


const root = createBrowserRouter([

  {
    path: "",
    element: <Suspense fallback={Loading}><Main/></Suspense>
  },
  {
    path: "about",
    element: <Suspense fallback={Loading}><About/></Suspense>
  },
  {
    path: "todo",
    element: <Suspense fallback={Loading}><TodoIndex/></Suspense>,
    children: todoRouter()
  }


])

export default root;
  • todoRouter
//todoRouter
import { Suspense, lazy } from "react";
import { Navigate } from "react-router-dom";

const todoRouter = () => {

  const Loading = <div>Loading....</div>
  const TodoList = lazy(() => import("../pages/todo/ListPage"));
  const TodoRead = lazy(() => import("../pages/todo/ReadPage"));
  const TodoModify = lazy(() => import("../pages/todo/ModifyPage"));
  const TodoAdd = lazy(() => import("../pages/todo/AddPage"));


  return [
    {
      path: "list",
      element: <Suspense fallback={Loading}><TodoList /></Suspense>
    },
    {
      path: "read/:tno",
      element: <Suspense fallback={Loading}><TodoRead /></Suspense>
    },
    {
      path: "modify/:tno",
      element: <Suspense fallback={Loading}><TodoModify /></Suspense>
    },
    {
      path: "add",
      element: <Suspense fallback={Loading}><TodoAdd /></Suspense>
    },
    {
      path: "",
      element: <Navigate replace to="/todo/list" />
    },

  ]
}


export default todoRouter;
  • App을 Router Provider로 감싸줘야함.
//app.js
function App() {
  return (
    <RouterProvider router={root}></RouterProvider>
  );
}

useSearchParams vs useNavigate

  • URL 전체를 이동할 때 => useNavigate

  • parameter를 바꿀때 => useSearchParams(리렌더링됨)


  const [qureyParams, setQueryParams] = useSearchParams();

useEffect 페이지네이션 활용

  • page가 변하지 않을때도 최신데이터를 받아오는 방법

  • refresh라는 state를 deps에 넣어서 관리함.

  • ListComponent의 key값을 api호출시마다 변경 => 항상 리렌더링 발생함 (근데 좋은 방법은 아닌듯?)

const ListComponent = ({ page, size, refresh }) => {

    useEffect(() => {
        getList({ page, size }).then(data => console.log(data));
    }, [page, size, refresh]); //page번호 바꾸면 최신데이터 받아옴.

    // page가 변하지 않는다면? 실시간으로 데이터가 안변함.
   

    return (<>
        <div>Todo List Component {page} ---- {size}</div>
    </>);
}


        <ListComponent page={page} size={size} key={key}></ListComponent>

JS 모듈패턴

  • JS 클로저를 이용한 패턴

  • 함수가 끝나고 나면 메모리 공간 초기화(지역변수)

=> 함수는 상태를 유지못함.

숨겨진 참조라는 뜻!!

import { useState, useCallback } from 'react';

function useInputs(initialForm) {
  const [form, setForm] = useState(initialForm);
  // change
  const onChange = useCallback(e => {
    const { name, value } = e.target;
    setForm(form => ({ ...form, [name]: value }));
  }, []);
  const reset = useCallback(() => setForm(initialForm), [initialForm]);
  return [form, onChange, reset];
}

export default useInputs;
  • 이 코드에서 onChange라는 함수는 form, setform을 참조

  • return시 form, onChange, reset만 return, setform을 외부에서 사용 할 수 없는 클로저형태임.

Error Boundary vs catch절

  • 라우터쪽에서 잡는경우 => Error Boundary를 많이 씀

  • 보통 세세한 에러잡을때는 catch절에서 잡음(이렇게 처리하는것도 나쁜 방법은 아님)

  • 비동기 처리할때 문제가 많이 되는데 => react Query사용해서 처리함

React Query의 활용

  • useQuery key에서 querykey시 배열에 여러가지 값을 줄 수 있음.

  • isFetching
    isFetching은 어떠한 react-query요청 내부의 비동기 함수가 처리되었는지 여부 에 따라 true/false로 나누어 짐.

  • 그럼 isLoading은?
    isLoading은 캐시된 데이터조차 없이, 처음 실행된 쿼리 일 때 로딩 여부에 따라 true/false로 나누어 진다.

  • 즉, 결론적으로 isLoading과 isFetching은 비슷하게 '로딩' 이라는 개념을 사용하지만 기존에 캐시된 데이터가 있느냐 에 따라 다르다.

  • 실시간성이 중요한 sns같은경우 refresh를 key로 주어서 사용가능(실시간 데이터 받아오는 형식) => 어떤 페이지냐에 따라 다르겠네요.

  • 정적데이터같은 경우 => page, size를 이용해 캐싱가능 => api호출을 줄인다.

  • 100% Real Time이 필요없을때 호출을 최소화 하고 싶으면 React Query사용이 맞음

  • Real Time의 성격이 강할때 Web Socket(ex) 채팅)

   const { isLoading, isFetching, data } =
         useQuery(["todo/list", { page, size, refresh}], () => getList({ page, size }), { staleTime: 1000 * 5 });
profile
응애 나 애기 개발자

0개의 댓글