웹풀스택 공부 중
13 - 3. React Hook 본문
React 공식 Hook
- 종류
- useState
- 간단한 상태 관리 + 자율성 보장
- useReducer
- 복잡한 상태관리 + 제약적
- State는 정해진 Action으로만 변경시킬 수 있음
- 상태 업데이트 로직(Reducer)를 Component에서 분리한다
- 복잡한 전이를 한곳에서 관리할 수 있다!
- 상태 업데이트 로직(Reducer)를 Component에서 분리한다
- Dispatcher (함수 실행기)와 Action(함수 실행에 필요한 Parameter)가 있다
- Dispatcher에 정해진 Action Type만 호출이 가능하다
- Dispatch는 상태변경 요청을 호출한다
[State, Dispatch] = useReduce
이런식으로 사용한다
- useState
전역 상태
Props Drilling 문제를 해결해준다
Props Drilling: 상위 App 부모에서 하위 TC 자식들까지 수직적 상태 전달을 위한 Props가 너무 많다
- 수직적 상태전달이 너무 많이 발생하는 현상
- S: 상태이자 Model
- V: View
- 단방향 바인딩, Single Source of Origin 때문에 발생한다
해결방법:
Context (맥략)을 만들어 공유하고자 하는 것들을 넘겨준다
- Context가 가지고 있기에 원하는 View에서 쓰고자하는 Props만 사용할 수 있다
Context가 만들고
누구에게 줄지 범주를 정하고 (= Provider)
소비한다 (= 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 |