const [state, dispatch] = useReducer(reducer, initialArg, init);
useState의 대체 함수라고 생각할 수 있다. 여러 개인 state를 묶어 사용한다.
(state, action) => newState의 형태로 reducer를 받고 dispatch 메서드와 짝의 형태로 현재 state를 반환한다.
많은 하위의 값을 포함하는 복잡한 정적 로직을 만들거나 다음 state가 이전 state에 의존적인 경우에 보통 useState보다 useReducer를 선호한다.
어떤 action인지에 따라 어떤 state를 선택할 것인지 선택한다. action도 type과 name을 가질 수 있다.
initialState : useState에서 처음에 초기 값을 설정해 줬던 것 처럼 여러 개의 State를 처음 초기와 하는 작업.
1. loginView 복사 파일을 만들고 그 파일에 useReducer를 만든다.
import React, { useReducer, useCallback } from "react";
2. 분리되어 있는 reducer 폴더에 reducer 파일을 만든다.
switch - case문을 이용하여 action type과 case를 설정 해준다.
loginView에 import 해서 사용한다.
const reducer = (state, action) => {
switch (action.type) {
case "PROCEED_STAGE":
return {
...state,
stageIdx: ++action.stageIdx,
};
case "NAME_CHECK":
return {
...state,
userInput: {
...state.userInput,
name: action.value,
},
};
case "ADD_USER_INFO":
return {
...state,
userInput: {
...state.userInput,
[action.inputName]: action.value,
},
};
case "ADD_ERROR_MSG":
return {
...state,
errorMsg: action.message,
};
default:
return state;
}
};
export default reducer;
3. loginView 이벤트 핸들러에서 dispatch를 사용하여 type을 확인 하고 값을 변경 한다.
const loginHandler = useCallback((e) => {
if (userName !== user[0].id) {
dispatch({
type: "ADD_ID_ERROR_MSG",
message: "아이디가 일치하지 않습니다.",
});
}
if (userPw !== user[0].password) {
dispatch({
type: "ADD_PW_ERROR_MSG",
message: "비밀번호가 일치하지 않습니다.",
});
}
if (userName === user[0].id && userPw === user[0].password) {
props.history.push(`/`);
} else {
console.log("아이디와 비밀번호를 확인해주세요");
}
}, []);
const value = useContext(MyContext);
context 객체를 받아 그 context의 현재 값을 반환한다.
context의 현재 값은 트리 안에서 이 Hook을 호출하는 컴포넌트에 가장 가까이 있는 <MyContext.Provider>의 value prop에 의해 결정 된다.
컴포넌트에서 가장 가까운 <MyContext.Provider>가 갱신되면 그 MyContext provider에게 전달된 가장 최신의 context value를 사용하여 렌더러를 트리거 한다.
useContext를 Context.Provider와 같이 사용한다.
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}