반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

웹풀스택 공부 중

13 - 3. React Hook 본문

웹개발/React

13 - 3. React Hook

lukeit 2024. 10. 31. 13:27

React 공식 Hook

  • 종류
    • useState
      • 간단한 상태 관리 + 자율성 보장
    • useReducer
      • 복잡한 상태관리 + 제약적
      • State는 정해진 Action으로만 변경시킬 수 있음
        • 상태 업데이트 로직(Reducer)를 Component에서 분리한다
          • 복잡한 전이를 한곳에서 관리할 수 있다!
      • Dispatcher (함수 실행기)와 Action(함수 실행에 필요한 Parameter)가 있다
        • Dispatcher에 정해진 Action Type만 호출이 가능하다
        • Dispatch는 상태변경 요청을 호출한다
        • [State, Dispatch] = useReduce 이런식으로 사용한다

전역 상태

  • Props Drilling 문제를 해결해준다

  • Props Drilling: 상위 App 부모에서 하위 TC 자식들까지 수직적 상태 전달을 위한 Props가 너무 많다

- 수직적 상태전달이 너무 많이 발생하는 현상
- S: 상태이자 Model
- V: View
- 단방향 바인딩, Single Source of Origin 때문에 발생한다
  • 해결방법:

    • Context (맥략)을 만들어 공유하고자 하는 것들을 넘겨준다

      • Context가 가지고 있기에 원하는 View에서 쓰고자하는 Props만 사용할 수 있다
      1. Context가 만들고

      2. 누구에게 줄지 범주를 정하고 (= Provider)

      3. 소비한다 (= Consumer)

    • 예시

      const CreatedContext = createContext(0); // 0은 initial value가 아닌, Default value이다
      
      function Count() {
      // useContext를 통해 전역 상태를 사용할 수 있다
        const count = useContext(CreatedContext);
      }
      
      function App() {
        //전역 상태
        const [count, setCount] = useState(0)
        return (
            <>
            {/* 부모 자식처럼 사용할 수 있따. 그래서 이 < > 에서만 사용이 가능하다. 여기에 있는 value가 initial value이다 */}
            <CreatedContext.Provider value = {count}>
                <Count />
                <button />
            <CreatedContext.Provider/>
        </>
      }
  • 거짓) Context 상태가 바뀜에 따라 Provider 내 모든 자식들이 Rerender된다

    • 잘못 사용하면 그렇게 된다

    • 발생한 이유: Context가 최상위 부모에 위치해서 그렇다.

    • 해결방법:

      • Context Provider를 새로운 Component로 만들고, 그 안에다가 State를 숨겨야한다

          import './App.css'
          import { produce } from 'immer'
          import { createContext, useContext, useState } from 'react'
        
          function LastComponent() {
            console.log('- A.4. Last Component')
            return <div className='component-box'>Last Component</div>
          }
        
          function ThirdComponent() {
            const { count } = useContext(CreatedContext)
            console.log('- A.3. Third Component')
            return (
              <div className='component-box'>
                Third Component
                <div>{count}</div>
                <LastComponent />
              </div>
            )
          }
        
          function SecondComponent() {
            console.log('- A.2. Second Component')
            return (
              <div className='component-box'>
                Second Component
                <ThirdComponent />
              </div>
            )
          }
        
          function FirstComponent() {
            console.log('- A.1. First Component')
            return (
              <div className='component-box'>
                First Component
                <SecondComponent />
              </div>
            )
          }
        
          function ButtonComponent() {
            const { setCount } = useContext(CreatedContext)
            console.log('- B. Button Component')
            return (
              <div className='component-box'>
                Button Component
                <button onClick={(e) => setCount((previous) => previous + 1)}>증가</button>
              </div>
            )
          }
        
          function NonContextComponent() {
            const { count } = useContext(CreatedContext)
            console.log('- C. Non-Context Component')
            return (
              <div className='component-box'>
                Non-Context Component<div>{count}</div>
              </div>
            )
          }
        
          const CreatedContext = createContext({ count: -10, setCount: (e) => {} } /* Default Value, DV */)
        
          function CreatedContextProvider({ children }) {
            const [count, setCount] = useState(0)
        
            return (
              <CreatedContext.Provider value={{ count, setCount }}>
                {children}
              </CreatedContext.Provider>
            )
          }
        
          function App() {
            return (
              <div
                className='section-box'
                style={{
                  display: 'flex',
                  justifyContent: 'center',
                  alignItems: 'center',
                  gap: 16,
                  padding: 10,
                }}
              >
                <CreatedContextProvider>
                  <FirstComponent />
                  <ButtonComponent />
                </CreatedContextProvider>
                <NonContextComponent />
              </div>
            )
          }
        
          export default App
        
반응형

'웹개발 > React' 카테고리의 다른 글

12 - 1. React 문법  (0) 2024.10.10
11 - 1. React  (3) 2024.10.10