const value = useContext(MyContext);
useContext
는 React.createContext
의 반환값인 context 객체를 인수로 받고, 현재 context value를 반환함useContext
의 인수는 반드시 context 객체이어야 함useContext
를 호출한 컴포넌트 상위의 가장 가까이 있는 <MyContext.Provider>
의 value
prop에 의해 결정됨<MyContext.Provider>
가 갱신되면, useContext
Hook은 <MyContext.Provider>
에 전달된 가장 최신의 context value를 가지고 리렌더링을 발생시킴useContext
를 사용한 컴포넌트는 context value가 변할 때 항상 리렌더링됨React.memo
나 shouldComponentUpdate
를 사용했더라도, useContext
를 사용한 컴포넌트는 여전히 리렌더링됨Tip
useContext(MyContext)
는 클래스에서의static contextType = MyContext
나<MyContext.Consumber
와 동등함useContext(MyContext)
는 context를 읽고, context의 변화를 구독하게 함- context에 value를 제공하기 위해 트리의 상위에
<MyContext.Provider
가 있어야함
const [state, dispatch] = useReducer(reducer, initialArg, init);
useReducer
useState
의 대체 Hook임(state, action) => newState
useReducer
의 반환값 : useReducer
현재 state와 연관된 dispatch
메서드dipatch
메서드의 identity는 안정적이고, 리렌더링할 때 바뀌지 않음useEffect
나 useCallback
의 dependency list에서 dispatch
가 생략되어도 안전함useReducer
를 사용함useReducer
는 깊은 업데이트 발생되는 컴포넌트에 대한 성능 최적화를 할 수 있음const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
useReducer
의 상태를 초기화하는 2가지 방법useReducer
의 2번째 인수로 초기 state를 전달함useReducer
의 3번째 인수로 초기 state를 설정하는 함수를 전달함// `useReducer`의 2번째 인수로 초기 state 전달
const [state, dispatch] = useReducer(
reducer,
{count: initicalCount}
);
// `useReducer`의 3번째 인수로 초기 state를 설정하는 함수를 전달
const init(initialCount) {
return {count: initialCount};
}
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
case 'reset':
return init(action.payload);
default:
throw new Error();
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialState, init);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'reset', payload: initialCount})}>Reset</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
useReducer
에서 반환한 값이 현재 state와 같을 때, React는 자식을 렌더링하거나 effect를 실행하지 않고 bail out함Object.is
비교 알고리즘을 사용하여 비교함