Javascript를 배우고 있습니다. 매일 배운 것을 이해한만큼 정리해봅니다.
지난 2주 프로젝트에서 React만을 이용해서 채팅 서비스를 구현했다. 처음에는 상태 관리가 그렇게 많이 필요할까 했는데 메인 채팅창을 구현해보고 나니 앱 전체에 20개 가까이 되는 상태가 존재했고, 형제 컴포넌트들에 영향을 주는 경우 state 끌어올리기를 해서 app.js와 mainPage.js가 비정상적으로 state 대두가 되어 있었다. 이벤트 핸들러도 state x n배였기 때문에 나중에는 어떤 핸들러 함수가 어느 컴포넌트에 있는지 기억해내는 것도 아주 골치가 아팠다.
오늘 따로 hooks를 살펴봤고, 그 내용을 간단히 정리한다.
const [state, setState] = useState(initialState);
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
useEffect(didUpdate);
useEffect(() => {
const subscription = props.source.subscribe();
return () => {
// Clean up the subscription
subscription.unsubscribe();
};
}); //},[]} <- componenetDidMount 시에만 가동하길 원하는 경우
const value = useContext(MyContext);
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>
);
}
<context객체명.Provider value={값}></ context객체명.Provider>
로 감싼다.useContext(context객체명)
를 변수에 담고, 사용하기 원하는 태그에서 value를 사용한다.const [state, dispatch] = useReducer(reducer, initialArg, init);
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>
</>
);
}
function 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, initialCount, 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를 useRender라고 잘못 쓰신 부분이 두군데 있어서 댓글 남겨봅니다.