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) => newStateuseReducer의 반환값 : 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 비교 알고리즘을 사용하여 비교함