diegohaz/constate

IAM에서 constate 라이브러리를 사용하고 있는데, 사용하면서 그냥 Context API 쓰는거랑 뭐가 다른지 크게.. 와닿지 않아서 이 기회에 공부해보고 싶고, IAM이나 다른 서비스들에 어떻게 사용해야 constate를 더 잘 활용할 수 있을 지 알아보기 위해 constate를 첫 떠스 주제로 골랐습니다! 👏🏻👏🏻👏🏻 Context API의 고수인 여러분께 전혀 어렵지 않은 내용이니 편하게 들어주세요!!! 🙇🏻‍♀️🙇🏻‍♀️🙇🏻‍♀️

Context API의 (재)등장과 그 한계

리액트 16.3 이 릴리즈 되면서, 기존에 존재하던 Context API 가 새로워졌다. 이미 kic2의 많은 프로젝트에서 Context API 가 사용되고 있으니, Context API 사용법이나 개념에 대한 설명은 생략한다.

아래는 Context API 를 적용한 매우 간단한 코드 예시다.

const KasperContext = createContext(null);

const KasperProvider = ({ children }) => {
  const [result, setResult] = useState(null);
  return (
    <KasperContext.Provider value={{ result, setResult }}>
      {children}
    </KasperContext.Provider>
  )
}

const useKasper = () => {
  return useContext(KasperContext);
}

const KasperResult = () => {
  const { result } = useKasper();
  return (
    <div>
      {result ? 
        <span>{result} 당첨!</span>
        :
        <span>추첨 결과가 없습니다. 버튼을 눌러 추첨을 하세요.</span>
      }
    </div>
  );
}

const KasperButton = () => {
  const { setResult } = useKasper();
  
  const members = ['jenny.je', 'dave.noh', 'jayjay.egg', 'joseph.song', 'luis.me'];

  const onClick = () => {
    var item = members[Math.floor(Math.random() * members.length)];
    setResult(item);
  }

  console.log('Button component rendered');
  return (
    <button onClick={onClick}>추첨하기</button>
  );
}

const App = () => {
  return (
    <KasperProvider>
      <KasperResult />
      <KasperButton />
    </KasperProvider>
  );
}

export default App;

RandomPickerProvider 에서 result 값과 그 result를 update하는 로직을 모두 전달하고 있다.

Context API에서 이런식으로 코드를 짜는 것은 아주 일반적이고 자연스럽지만, 문제(개선 가능성..?)가 있다.

따라서, Context API를 사용할 때, Context들을 적절히 쪼개주는 작업이 필요하다. 위 예시에서 Context를 쪼개줘봤다.

const KasperResultContext = createContext(null);
const KasperResultUpdateContext = createContext(null);

const KasperProvider = ({ children }) => {
  const [result, setResult] = useState(null);
  return (
    <KasperResultContext.Provider value={result}>
      <KasperResultUpdateContext.Provider value={setResult}>
        {children}
      </KasperResultUpdateContext.Provider>
    </KasperResultContext.Provider>
  );
}

const KasperResult = () => {
  const result = useContext(KasperResultContext);
  // ...이하 동일
}

const KasperButton = () => {
	const setResult = useContext(KasperResultUpdateContext);
  // ...이하 동일
}