Recoil

김정욱·2021년 7월 10일
0

React

목록 보기
22/22
post-thumbnail

refs :
https://velog.io/@juno7803/Recoil-Recoil-200-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0#%EB%8F%99%EC%A0%81%EC%9D%B8-url%EC%97%90-%EB%8C%80%ED%95%9C-api-call---selectorfamily-

[ React와 MVC / Flux ]

  • React와 MVC 패턴
    • 초기에는 MVC 디자인 패턴을 통해 주로 개발이 이루어졌다
  • React에서 MVC의 문제점
    • MVC 패턴은 Model과 View가 소통하며 서로 양방향으로 영향을 주며 데이터의 흐름을 가진다는 특징이 존재
    • App의 규모가 커질수록 영향이 커져서 예측 불가능하고, 그에 따라 버그가 발생하기도 했음
      (Facebook에서 대표적으로 알람 기능 버그를 예시로 들었음)
  • Flux 패턴의 등장
    • Facebook 에서는 양뱡항의 데이터 흐름을 문제라고 생각하였고, 단방향 데이터 흐름 패턴을 만듬
    • Flux 패턴을 구현한 구현체 중 가장 많이 사용되는 것이 바로 우리가 아는 Redux
  • Flux 패턴의 단방향 흐름
    • Dispatcher
      Dispatcher는 Flux의 모든 데이터 흐름을 관리하는 허브 역할을 하는 부분입니다. Action이 발생되면 Dispatcher로 전달되는데, Dispatcher는 전달된 Action을 보고, 등록된 콜백 함수를 실행하여 Store에 데이터를 전달합니다. Dispatcher는 전체 어플리케이션에서 한 개의 인스턴스만 사용됩니다
    • Store
      어플리케이션의 모든 상태 변경은 Store에 의해 결정이 됩니다. Dispatcher로 부터 메시지를 수신 받기 위해서는 Dispatcher에 콜백 함수를 등록해야 합니다. Store가 변경되면 View에 변경되었다는 사실을 알려주게 됩니다. Store은 싱글톤으로 관리됩니다.
    • View
      Flux의 View는 화면에 나타내는 것 뿐만이나라, 자식 View로 데이터를 흘려 보내는 뷰 컨트롤러의 역할도 함께 합니다.
    • Action
      Dispatcher에서 콜백 함수가 실행 되면 Store가 업데이트 되게 되는데, 이 콜백 함수를 실행 할 떼 데이터가 담겨 있는 객체가 인수로 전달 되어야 합니다. 이 전달 되는 객체를 Action이라고 하는데, Action은 대채로 액션 생성자(Action creator)에서 만들어집니다.

[ 등장 배경 ]

  • React는 단방향 (부모 -> 자식)으로 값(props)를 전달한다
    • 자식에서 부모에게 props를 전달할수는 없음
    • 자식에서 부모의 state를 바꿀 수 있는 방법은 2가지가 존재
      • 부모가 setState 함수를 props로 넘겨서 자식에서 호출하는 방법
        --> 규모가 커질수록 관리가 힘들어짐
        --> 그래서 등장한 것이 바로 아래의 Redux / mobx / Recoil
      • state management tool을 사용하는 방법(Redux / Recoil)
  • Facebook에서 제안한 Flux 아키텍처를 사용한 구현체가 바로 Redux
  • Redux는 처음 배우기에 러닝 커브가 높고, 복잡하며, React에 최적화 되어있지는 않다
    --> 그래서 등장한 Recoil이 바로 React를 위한 상태관리 라이브러리 이다!

[ 설명 ]

  • 정의 : React를 위한 상태 관리 라이브러리
  • 핵심 개념
    • atom
      • 상태의 단위
      • Redux의 store와 비슷한 역할
      • atom은 업데이트와 구독이 가능
      • atom을 업데이트 하면, atom을 구독한 모든 컴포넌트의 State는 업데이트 되고 re-render 수행
    • selector
      • atom이 가진 State를 가공하여 반환할 수 있음
      • 파생된 State를 나타내는데 사용
      • atoms 상태값을 동기 또는 비동기 방식을 통해 변환
      • 비동기 수행을 할 수 있음(서버 통신에 사용 가능)
  • 핵심 api
    • useRecoilValue() : State의 Value
    • useSetRecoilState() : State를 수정하는 setter
    • useRecoilState() : State의 Value와 setter를 함께 사용할 수 있는 기능
  • 비동기 작업의 상태를 관리하기 위해 Suspense / Loadable 사용 가능
    • React.Suspense
    • Recoil의 Loadable
    • 추가적으로 React Query를 사용해서 해결할수도 있음

[ 사용 예시 ]

[ 기본적인 atom / selector 사용 ]

/* atom 생성 */
const textState = atom({
	key: 'textState', // unique ID(다른 atom/selectors 와 구별하기 위함)
	default: '', // default value (=initial value)
})

/* selector 생성 -> atom을 가공해서 사용 가능 */
const charCountState = selector({
  key: 'charCountState', // unique ID (with respect to other atoms/selectors)
  get: ({get}) => {
    const text = get(textState);
    return text.length;
  },
});

/* atom 구독 */
function TextInput() {
	const [text,setText] = useRecoilState(textState);
	//const text = useRecoilValue(textState);
	//const setText = useSetRecoilValue(textState);

	const onChange = (event) => {
		setText(event.target.value);
	};
	...
}

[ selector로 비동기 통신 ]

(state.js)

export const githubRepo = selectorFamily({
  key: "github/get",
  get: (githubId) => async () => {
    if (!githubId) return "";

    const { data } = await axios.get(
      `https://api.github.com/repos/${githubId}`
    );
    return data;
  },
});

(Github.js)

import { useRecoilValue } from 'recoil';
import { selectorFamily } from '../../state';
const Github = () => {
  const githubId = 'juno7803';
  const githubRepos = useRecoilValue(githubRepo(githubId));

  return(
    <>
      <div>Repos : {githubRepos}</div>
    </>
  )
}
export default Github;
profile
Developer & PhotoGrapher

0개의 댓글