Hooks(1) 에서 정리한것에서 이어서 작성해보려고 한다.😊
useRef Hook은 함수 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해준다. 지난번에 정리한 클래스컴포넌트에서 ref를 사용하는 방법에선 콜백 함수를 통한 설정과 createRef를 통한 ref설정을 했었다. 오늘은 Hook을 이용한 방법을 정리해보자.
import { useState, useMemo, useCallback, useRef } from 'react';
const getAverage = numbers => {
console.log('평균값 계산 중');
if(numbers.length === 0 ) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
}
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
//useRef추가
const inputEl = useRef(null);
//useCallBack를 사용해 최적화! 컴포넌트가 처음 렌더링 될때만 함수 생성
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []);
//useCallBack를 사용해 최적화! number, list가 바뀌었을 때만 함수 생성
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
inputEl.current.focus();
}, [number, list]);
const avg = useMeno(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} ref={inputEl}/>
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) =>(
//리액트에서 배열만들때에는 key props는 필수!
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
useRef를 사용하여 ref를 설정하면 useRef를 통해 만든 객체 안의 current 값이 실제 엘리먼트를 가리킨다.
여러개의 컴포넌트에서 비슷한 기능을 공유할 경우, Hook을 커스텀해 로직을 재사용할 수 있다. 이를 사용하기 위해선 useReducer가 필요하다.
✔ 커스텀 hook 만들기
import { useReducer } from 'react';
//리듀서에서는 기존상태값과 디스패치할 액션값이 필요하다.
function reducer(state, action) {
return {
//기존의 상태값을 꼭 복사후에 아래에 변경되는 값만 다시 설정해주기!
...state,
[action.name]: action.value
};
}
export default function useInputs(initialForm) {
const [state, dispatch] = useReducer(reducer, initialForm);
const onChange = e => {
dispatch(e.target);
};
return [state, onChange];
}
✔ 커스텀 hook 사용하기
const Info = () => {
const [state, onChange] = useInputs({
name: '',
nickname: ''
});
const { name, nickname } = state;
return (
<div>
<div>
<input value={name} onChange={onChange}/>
<input value={nickname} onChange={onChange}/>
</div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b> {nickname}
</div>
</div>
)
}
export default Info;
반복되던 onChangename/nickname를 커스텀훅을 사용해 압축하니 훨씬 깔끔해졌다.
리액트에서 Hooks 패턴을 사용하면 클래스형 컴포넌트를 작성하지 않고도 대부분의 기능을 구현할 수 있다. 하지만 리액트 매뉴얼에 따르면, 기존의 클래스형 컴포넌트또한 앞으로도 계속해서 지원될 예정이라고한다. 그렇기 때문에 유지 보수를 하고있다면 클래스형 컴포넌트의 지식또한 알고있었야한다.
리액트를 다루는 기술을 읽고 요약한 글 입니다😊