REST

웹 아키텍처 스타일 중 하나이며, 사실상 웹 아키텍처의 표준 URI로 자원을 식별하고, HTTP 메서드(GET/POST/DELETE 등)를 통해 자원을 조작

STATE 변경이 되는 데이터들

REST의 표현

  • JSON, XML, HTML 등
  • XML은 계층적인 데이터 구조를 정의
  • 데이터를 문자열로 받을 수 있고, Key-value 구조처럼 받을 수도 있음. 이들이 하나의 표현 방법이고, 선택함

Transfer

  • URI와 HTTP 메서드를 활용해 클라이언트와 서버 간에 교환되는 과정

RESTful의 특징

  • 모든 것이 자원(Resource)
    • URI를 통한 자원의 식별
    • 고유한 id를 부여해서 나중에라도 들어가도 똑같이 볼 수 있도록 설계해야 함
  • 자원은 다양한 형태로 표현함
  • stateless
    • 서버는 클라이언트 상태를 기억하지 않음
    • 페이지 단위 개발의 경우에는 상태 저장(세션 정보)을 서버에서 저장.
    • 누구한테 줬는지 확인하지 않음
    • 서버는 단순해지고, 확장성 용이
  • 캐시 가능
    • 캐시는 백엔드에서 redis 등 효과적으로 하기 위해 캐시를 둠
    • 클라이언트에서도 캐시 처리에 대한 방법이 많음
      • React-Query
      • Apollo Client
      • Service-worker
      • 캐시가 브라우저에 저장되는 방식
    • 중복 요청 방지
    • 응답 헤더에 Cache-control, Expires
  • layered System
    • 캐시 서버, 웹서버, 프록시 서버, L4…
  • Uniform Interface
    • URI
    • Status code
    • HTTP 기반 메서드를 활용해서 자원의 조작 가능
  • stateless로 충분한가? 언제 statefulgksrk?
    • stateless에서는 연속된 요청에서 데이터 양이 증가하는 문제
    • 쿠키? 세션
    • 개인화, 인증, 권한 관리 등
    • 두 가지의 균형이 중요

커스텀 훅

  1. 중복 요소 분리하기
  2. 렌더링 영향도가 낮은 상태(전처리 영역)
  3. 사실 suspense와 error boundary쓰면 됨

재사용 컴포넌트

컴포넌트란?

  • 컴포넌트는 무엇인가?
    • 의미있는 요소. (modal, calendar, navigation, slider, UI의 독립적인 화면단위 등)
    • React 컴포넌트
  • 재사용을 해야하는가?
    • 반복 또는 중복인가?
  • 현실은?
    • 화면은 조금만 달라도 재사용은 어렵다. 😣 동작, 스타일 등
  • 만약 여러개의 상태를 공유하는 법
    • 하나의 상태를 공유한다고 할 때 한 쪽에는 함수를 넣어주고, 이벤트 이미터와 비슷한 방식으로 이벤트를 호출하는 방법도 있고, 동작하고자 하는 함수를 전달하는 방법도 있음

리액트 상태관리 - Flux & useReducer

Flux 아키텍쳐

Redux : Flux 아키텍쳐 기반 라이브러리

  • unidirection data flow
  • action 을 전달
  • store에서 데이터 변경 관리
  • view는 store를 구독하는 방식

//view에서
dispatch({
  type: 'deposit',
  payload: 10
})
 
//reducer에서
 switch (action.type) {
    case "deposit":
     	return {
        action.payload
      }
     ....
   .....

useReducer Hooks API - flux 아키텍쳐를 따름

useReducer API

복잡한 상태관리에서 useState보다 유리하다.
구체적인 상태변경을 감추고, reducer에 맡길 수 있다.
또한 콜백(setState 등)을 계속 하위component 에 전달해줘야 하는 불편함을 줄일 수 있다. 대신 dispatch라는 매개체 역할의 함수를 전달해준다.

참고 : https://react.dev/reference/react/useReducer

const initialState = {count: 0};
 
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}
 
function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

useReducer + Context API

  • Hooks API에서도 Flux architecture 를 따르며 개발 가능.
  • view 에서 상태변경 로직도 분리.
  • “그렇다면 Redux를 어느정도 대체가능?”
  • Context API 조합으로 같이 사용하면 어떨까?
const postReducer = (posts, { type, payload }) => {
  switch (type) {
    case 'SET_INITIAL':
      return [...payload];
    case 'ADD_POST':
      return [...posts, { title: payload, id: posts.length + 1, picked: false }];
    case 'TOGGLE_PICKED':
      return posts.map(post =>
        post.id === payload ? { ...post, picked: !post.picked } : post
      );
    default:
      return posts;
  }
};
 
export const PostsContext = React.createContext();
 
const App = () => {
  const [posts, dispatch] = React.useReducer(postReducer, []);
 
  const addItemHandler = () => {
    const newTitle = prompt("Enter new post title");
    if (newTitle) {
      dispatch({ type: 'ADD_POST', payload: newTitle });
    }
  };
 
  return (
    <PostsContext.Provider value={{ posts, dispatch }}>
      <PickedItems posts={posts} />
      <button onClick={addItemHandler}>ADD</button>
      <Items posts={posts} />
    </PostsContext.Provider>
  );
};

pure function은 순수 함수로 제작 테스트 하기가 용이함(예측이 쉬움

  • 테스트 가능성