context 에서 상태관리 하기

미마모코딩·2023년 11월 25일

저번 시간에는 createContext,useContext를 사용한 데이터를 넘겨주는 방법을 공부했다.

오늘은 context에서 상태관리를 하는 부분을 공부해보자.

먼저 간단한 카운터를 구현하는것이다.

아래 코드를 살펴보자.

<script>

import { createContext, useContext, useState } from 'react';

const CounterContext = createContext() //context만들기

const CounterProvider = ({children})=>{
   const value =  useState(1)
  return(
  <>
  {/* useState의 initialValue 1이 프로바이더의 value로 들어감 */}
    <CounterContext.Provider value ={value}> 
      {children}
    </CounterContext.Provider>
  </>
 )
}

const useCounterState =()=>{
  const counter = useContext(CounterContext) //여기는 useState의 1이 counter에 할당됨
  if(counter === "undefined"){
    throw new error ("error!")
  }
  return counter
}




function App() {
 
  return (
    <CounterProvider>
    <div>
      <Counter />
      <Button />
    </div>
    </CounterProvider>
  );
}

const Counter =()=>{
  const [count] = useCounterState() // useState의 값 꺼내오기 
  return(
    <h1>
      {count}
    </h1>
  )
}
const Button =()=>{
  const [,setCount] = useCounterState() //set해서 값 변경하기 
  const increase = ()=>{
    setCount((prev)=>prev + 1)
  }
  const decrease = ()=>{
    setCount((prev)=>prev - 1)
  }
  return(
    <div>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  )
}


export default App;
</script>

위코드에서 차근차근 설명해보겠다.
우리가 context에서 상태관리를 하려면 우선 provider를 따로 만들어주는게 좋다.
이유는 다음과같다.

CounterProvider

1.중앙 집중식 상태 관리: 구성 요소 를 생성하여 CounterProvider카운터의 상태 관리를 중앙 집중화했다. 간단하게 풀어서 생각하면 카운터 상태와 관련된 데이터를 캡슐화 하기 좋기때문이다.

2.확장성: 애플리케이션이 성장하고 더 많은 전역 상태를 관리해야 하는 경우 중앙 집중식Provider를 사용하면 CounterProvider확장하기가 더 쉽다. Provider에 더 많은 상태 변수를 추가할 수 있으며 해당 상태에 액세스해야 하는 구성 요소는 추가 사용자 지정 후크를 사용할 수 있다.

위와 같은 이유로 우리는 children이라는 props를 받아 또다른 하나의 CounterProvider를 생성했다.

Custom hook

<script>
const useCounterState =()=>{
  const counter = useContext(CounterContext) //여기는 useState의 1이 counter에 할당됨
  if(counter === "undefined"){
    throw new error ("error!")
  }
  return counter
}
</script>

위코드를 이해해보자 . useContext를 사용하여 CounterContext의 값을 counter라는 변수에 할당했다.
그리고 provider에서 값이 제대로 공급되지 않으면 undefined를 반환하기 때문에 에러를 발생하게했다.
우리는 위 커스텀훅을 사용할것이다.
counter에 할당된 값은 알고있겠지만 1이다. 하지만 그냥 1이아닌 useState의 초기값 1이다.
이게 어떤 것을 의미할까?
다음부분으로 넘어가보자.

Counter,Button

<script>
const Counter =()=>{
  const [count] = useCounterState() // useState의 값 꺼내오기 
  return(
    <h1>
      {count}
    </h1>
  )
}
const Button =()=>{
  const [,setCount] = useCounterState() //set해서 값 변경하기 
  const increase = ()=>{
    setCount((prev)=>prev + 1)
  }
  const decrease = ()=>{
    setCount((prev)=>prev - 1)
  }
  return(
    <div>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  )
}
</script>

위 코드를 살펴보자 우리는 useCounterState라는 custom hook을 사용하여 배열 비구조화 할당을 통해
값을 꺼내
왔다. 물론 count의 값은 1일것이다.

ButtonComponent를 살펴보자.

const [,setCount] = useCounterState() 이 부분이 생소할 수 있지만 이부분은 useState에서 set함수만 사용하겠다라는 의미랑 일치한다.
그래서 업데이트 함수만 추출하여 우리가 Provider에서 공급했던 기본값 useState의 value를 업데이트 하는 로직이다.

<script>
function App() {
 
  return (
    <CounterProvider>
    <div>
      <Counter />
      <Button />
    </div>
    </CounterProvider>
  );
}
</script>

위와같이 CounterProvider로 컴포넌트들을 감싸주었고 CounterProvider가 return 하는 값은

<script>
const CounterProvider = ({children})=>{
   const value =  useState(1)
  return(
  <>
  {/* useState의 initialValue 1이 프로바이더의 value로 들어감 */}
    <CounterContext.Provider value ={value}> 
      {children}
    </CounterContext.Provider>
  </>
 )
}
</script>

이기 때문에 CounterContext.Provider value ={value}와 동일하다.

오늘은 context내에서의 상태관리를 배웠다.

https://velog.io/@velopert/react-context-tutorial#context-%EC%97%90%EC%84%9C-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EA%B2%BD%EC%9A%B0를 참고하여 작성하였고
이해하기까지 시간이 조금 걸렸기에 내가 공부하고 이해하려는 용도로 포스팅을 하였다.

0개의 댓글