-
Notifications
You must be signed in to change notification settings - Fork 3
React Hooks API
이 프로젝트는 React Hook을 학습하기 위해 의도적으로 React Function Component만 사용하였습니다. Hook API는 React 16.8부터 사용할 수 있습니다.
Hook API에 대한 자세한 설명은 React Hook 가이드를 참고해주세요.
React Component에서 State
와 Lifecycle
을 사용하려면 Class Component를 사용해야 했지만 Hook API의 추가로 Function Component에서도 State
를 사용할 수 있게 되었습니다.
Lifecycle
은 전부 사용할 수는 없고 componentDidMount
, componentWillUnmount
를 유사하게 구현할 수 있습니다.
const refContainer = useRef(initialValue)
// refContainer.current === initialValue
useRef
는 initialValue
로 전달된 값을 current
라는 프로퍼티에 저장하고 변경가능한 순수 자바스크립트 객체를 반환합니다. Function Component 안에서 작성한 변수는 렌더링 될 때마다 초기화되는데, useRef
를 사용하면 동일한 객체가 유지됩니다. useRef
로 생성된 객체는 값을 변경해도 리렌더링되지 않습니다.
function TextInputWithFocusButton() {
const inputEl = useRef(null)
const onButtonClick = () => {
inputEl.current.focus()
}
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</div>
)
}
위 예제 출처 : https://ko.reactjs.org/docs/hooks-reference.html#useref
const [state, setState] = useState(initialState)
useState
는 상태 값과 그 값을 갱신하는 함수를 반환합니다. initialState
는 상태 값의 초기 값으로 사용되며 최초 렌더링에서만 사용됩니다.
import React, { useState } from 'react'
function Example() {
// "count"라는 새로운 상태 값을 정의합니다.
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
주의사항으로 Class Component의 setState와 다르게 이전 객체와 갱신 객체를 자동으로 합쳐주지 않습니다.
setState(prevState => {
return {...prevState, ...updatedValues}
})
위 예제 출처 : https://ko.reactjs.org/docs/hooks-reference.html#usestate
useEffect(effect: React.EffectCallback, deps?: React.DependencyList | undefined): void
State
나 Props
가 변경되었을 때 effect
인자에 입력한 Callback 함수를 실행합니다. 얼핏 보면 componentDidUpdate
와 비슷해 보이지만 useEffect
는 브라우저가 화면을 다 그릴 때까지 Callback 함수 실행을 지연시킵니다.
useEffect(() => {
state.hasMapData && methods.calcMapSize()
}, [state.hasMapData])
특정 값이 변경될 때만 useEffect
를 사용하고 싶다면 두번째 인자인 deps
에 의존성을 추가하시면 됩니다.
이 useEffect
는 state.hasMapData
이 변경될 때만 Callback 함수를 실행합니다.
useEffect(() => {
methods.paintLadder()
window.addEventListener('resize', methods.handleWindowResize)
return () => {
window.removeEventListener('resize', methods.handleWindowResize)
}
}, [])
만약 useEffect
를 첫번째 렌더링에서만 사용하고 싶다면 deps
에 []
빈 배열을 입력하시면 됩니다. 의존성이 없기때문에 컴포넌트가 mount 되거나 unmount 할 때 실행되게 됩니다. 그리고 effect
함수 내의 Props
와 State
는 초기 값이 유지되므로 주의하셔야됩니다.
useEffect
는 effect
함수 내에서 함수를 return
하여 clean-up
함수를 만들 수 있습니다. clean-up
함수는 컴포넌트가 제거되거나 재렌더링으로 인해 effect
함수가 다시 실행될 때 실행됩니다.
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialArguments, initializer)
useReducer
는 useState
의 대체 함수입니다. 다수의 하윗값을 포함하는 복잡한 객체나 다음 state가 이전 state에 의존적인 경우에 보통 useState보다 useReducer를 선호합니다.
아래는 useReducer
의 예제입니다.
const CHANGE_NAME = 'CHANGE_NAME'
const initialState = {
playerName: '',
}
const actions = {
changeName: (playerName: string) => {
return {
type: CHANGE_NAME,
payload: {
playerName,
},
}
}
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case CHANGE_NAME: {
state.playerName = action.payload.playerName
return state
}
default: {
throw new Error()
}
}
}
const ExamplePage: NextPage = () => {
const [store, dispatch] = useReducer(IndexReducer, initialState)
const changeName = e => {
dispatch(actions.changeName(e.target.value))
}
return (
<DefaultLayout>
<Text>{store.playerName}</Text>
<TextField onChange={changeName} />
</DefaultLayout>
)
}
https://github.com/divlook/ladder-game/blob/v0.1.3/reducers/index.type.ts
https://github.com/divlook/ladder-game/blob/v0.1.3/reducers/index.action.ts
https://github.com/divlook/ladder-game/blob/v0.1.3/reducers/index.reducer.ts
https://github.com/divlook/ladder-game/blob/v0.1.3/pages/index.tsx
useCallback(callback: T, deps: React.DependencyList): T
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
)
예제 출처 : https://ko.reactjs.org/docs/hooks-reference.html#usecallback
useCallback
은 메모이제이션된 콜백을 반환합니다. Function Component 내에서 선언된 콜백 함수를 자식 컴포넌트에게 전달할 때 useCallback
을 사용하지 않으면 부모 컴포넌트의 재렌더링 여부와 상관없이 자식 컴포넌트는 Props
변경되어 계속해서 재렌더링 될 것입니다. useCallback
은 의존성(deps
) 값이 변경되지 않으면 동일한 값을 참조하여 자식 컴포넌트의 불필요한 재렌더링을 방지할 수 있습니다.