[React] 상태관리 - serverState , clientState, persistState (작성중)

8658 단어 ReactReact

상태관리

목적 : serverState , clientState, persistState 를 관리하자.

개요

리액트 클라이언트의 상태는 ServerState + ClientState로 나뉜다.

t1 시점에서 서버에서 데이터를 가져온것도 하나의 상태 s1 이고
t2 시점에서 데이터를 가져온것 또한 상태 s2가 될 수 있다.
이렇게 세션간에 비동기적으로 관리하는 데이터를 서버 상태이다.

react-query 라는 라이브러리를 통해, 관리를 할 예정이다.
바로 눈에 뛰는 얻을 수 있는 이점은 다음과 같다.

  1. 서버에서 가져온 상태를 바로 캐싱한다. ( 서버데이터 -> react )
  2. 다른 뷰에서 같은 쿼리 요청이 생성되면 캐쉬된 데이터를 준다. ( 클라이언트 캐쉬 -> react )
  3. 주기적으로 서버의 상태를 가져온다. 예를들어 10초마다 백그라운드에서 데이터를 refresh 한다.
  4. 쿼리 요청 실패시, 3번 리트라이(기본), 리트라이 간격은 ?
  5. cache invalid 해야하는 시점은 ? , 그때 자동으로 react-query가 데이터 가져옴

Server 상태정의

- 1. NestJS에서 사용하는 entity,dtos를 가져와 interface를 정의
eg) export interface User {...}
eg) export interface UserLoginOutput {...}

- 2. Axios객체로 API Endpoint를 설계한다.
eg) return axios.get("/api/getUser")

- 3. 비슷한 기능을 훅으로 만들어서 추상화 한다.
eg) 로그인 - 나의 정보 - 프로필업데이트 - 로그아웃
eg) 전략검색-전략리스트뷰(조회순)-전략리스트뷰(분류)-전략생성-전략수정-전략가동-전략삭제

- 4. cache invalid 할 경우를 고려하자.
eg) 사용자 프로필 업데이트 이후 - 나의정보 쿼리 인스턴스는 invalid & refresh 하도록

- 5. query retry n번 모두 실패시, 애러 핸들링 (애러페이지) 어떻게 표현할지 고려
eg) retry 다 끝나면 -> 애러관리컴포넌트의 state 변화

Server 상태관리

index

- axios 에서 애러 핸들링
- axios를 감싸는 react-query의 애러 핸들링

(사전지식) axios 애러 핸들링

  • 시나리오 : 로그인 하려고 하는데,(어이쿠..!) body 정보를 주지 않았다.
  • 그래서 서버는 400 응답을 주고, error.response에 정보를 담아준다.
  • postman 요청시 보여주는 애러 정보는 사실 error?.response.data 객체 이다. (아래와 같음)
{
    "statusCode": 400,
    "message": [
        "email_id must be an email",
        "password must be a string"
    ],
    "error": "Bad Request"
}
  • axios에서는 다음 처럼 참조 및 핸들링 한다.
try:
// case. 성공적으로 요청이 이루어진 경우
catch:
// case1. 요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답했습니다.
// case2. 요청이 이루어 졌으나 응답을 받지 못했습니다.
// case3. 오류를 발생시킨 요청을 설정하는 중에 문제가 발생했습니다.
const loginMemberInfo = async (body: loginMemberInfoInput) => {
  try {
    const res = await axios.post("member/login-member-info");
    // case. 성공적으로 요청이 이루어진 경우
    return res.data as loginMemberInfoOutput;
  } catch (error) {
    // case1. 요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답했습니다.
    if (error.response) {
      console.log(
        "요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답."
      );
      console.log(error?.response.data); // 애러의 응답안에 들어 있다.
      // {statusCode: 400, message: Array(2), error: "Bad Request"}error: "Bad Request"message: (2) ["email_id must be an email", "password must be a string"]0: "email_id must be an email"1: "password must be a string"length: 2__proto__: Array(0)statusCode: 400__proto__: Object
      console.log(error?.response.status);
      // 400
      console.log(error?.response.headers);
      // {content-length: "108", content-type: "application/json; charset=utf-8"}
    }
    // case2. 요청이 이루어 졌으나 응답을 받지 못했습니다.
    else if (error?.request) {
      console.log("요청이 이루어 졌으나 응답을 받지 못했습니다.");
      // `error?.request`는 브라우저의 XMLHttpRequest 인스턴스 또는
      // Node.js의 http.ClientRequest 인스턴스입니다.
      console.log(error?.request); // XMLHttpRequest
    }
    // case3. 오류를 발생시킨 요청을 설정하는 중에 문제가 발생했습니다.
    else {
      console.log("Error?", error?.message);
    }
  }
};
  • 위 axios 요청의 애러를 핸들링하면, react-query는 무조건 요청이 성공으로 보게된다.

Client 상태관리

(이어서...)

좋은 웹페이지 즐겨찾기