Hooks 란 ?
리액트 V16.8에 새로 도입된 기능으로 함수형 컴포넌트에서도 상태관리를 할수 있는 useState 렌더링 직후 작업을 설정하는 useEffect 등의 기능을 제공 하여 기존의 함수형 컴포넌트에서 할수 없었던 다양한 작업을 할수 있게 해준다.
즉 클래스 형태에서 리액트를 구현 한던걸 함수 방식으로도 구현이 가능 하도록 해준게 hooks 라는 말 같다.
이제 부터 hooks 기능을 설명 하나씩 살펴 보겠습니다.
- useState : 가장 기존적인 hook 이며 컴포넌에서 상태 관리를 해야 한다면 이 hook를 사용 하면 됨.
import React from "react";
const Counter = () => {
const [value, setValue] = useState(0); // 0으로 초기화
return (
<div>
<p>
현재 카운터 값은 <b>{value}</b> 입니다.
</p>
<button onClick={() => setValue(value + 1)}>+1</button>
<button onClick={() => setValue(value - 1)}>-1</button>
</div>
);
};
value : 상태값
setValue : 상태를 설정하는 함수
useState 첫번째 값은 상태값 두번째 원소는 상태를 설정 하는 함수를 뜻한다.
- useEffect : 컴포넌트 렌더링이 될떄 마다 특정 작업을 수행 할수 있도록 설정 하는 hook 클래스형에서는 componentDidMount,componentDidupdate를 합친 형태랑 비슷 하다.
import React, { useState, useEffect } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
useEffect(() => {
console.log("렌더링 완료");
console.log({
console.log(nickname);
console.log(name);
});
return () => { //리턴을 사용 하게 되면 해당 렌더링 숨김 할때 실행 된다.
console.log("cleaup");
console.log(name);
};
},[]); // []를 사용 하게 되면 인풋창이 업데이트시 매번 실행 됐던게 처음 렌더링 시점에 실행된다.
//그리고 처음 렌더링 시점이 아니고 name 값이 변경될떄 실행 하고 싶다면 [name] 넣으면됨
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickname = e => {
setNickname(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름 :</b>
{name}
</div>
<div>
<b>닉네임 :</b>
{nickname}
</div>
</div>
</div>
);
};
값이 다 변경 되고 페이지 변경이 완료되는 시점에 useEffect 함수가 실행 된다.
- useReducer : useSate 보다 다양한 컴포넌트 상황에 따라 값을 업데이트 해주고 싶을떄 사용 하는 hook useState 는 값이 변경 될떄만 사용 하지만 useReducer 파라미터 값을 넘겨줘서 조건문을 넣어서 사용 할수 있다. 예시를 보면 알수 있을것이다.
import React, { useReducer } from "react";
function reducer(state, action) {
console.log(state);
switch (action.type) { //type 를 받아서 조건을 나눠서 처리가 가능 하다.
case "INCREMENT":
return { value: state.value + 1 };
case "DECREMENT":
return { value: state.value - 1 };
default:
return false;
}
}
const Counter = () => {
const [state, setValue] = useReducer(reducer, { value: 0 });
// useReducer 함수 첫번째 소요에 실행된 함수를 넣어 준다.
return (
<div>
<p>
현재 카운터 값은 <b>{state.value}</b> 입니다.
</p>
<button onClick={() => setValue({ type: "INCREMENT" })}>+1</button>
//INCREMENT 조건에는 +1을해주고 있다.
<button onClick={() => setValue({ type: "DECREMENT" })}>-1</button>
//DECREMENT 조건에는 -1을해주고 있다.
</div>
);
};
useReducer을 통해 input 상택 값을 조절 할수도 있다. input 이 여러개 일때 하나로 사용 가능하다.
예시를 보는게 이해에 도움이 될듯 하다.
import React, { useReducer } from "react";
function reducer(state, action) {
console.log({
...state, //name: state.name,nickname: state.nickname 같은 의미
[action.name]: action.value
});
return {
...state //name: state.name,nickname: state.nickname 같은 의미
[action.name]: action.value
};
}
const Info = () => {
const [state, dispatch] = useReducer(reducer, {
name: "",
nickname: ""
});
const { name, nickname } = state;// name, nickname 을 state 오르젝트에 담아서 하나로 사용.
const onChange = e => {
dispatch(e.target);
//input을 통으로 넘겨 준다. 이걸로 인해 input 여러가지 일때도 하나로 재활용이 가능.
};
return (
<div>
<div>
<input name="name" value={name} onChange={onChange} />
<input name="nickname" value={nickname} onChange={onChange} />
</div>
<div>
<div>
<b>이름 :</b>
{name}
</div>
<div>
<b>닉네임 :</b>
{nickname}
</div>
</div>
</div>
);
};
export default Info;
- useMemo : 컴포넌트 내부에서 발생 하는 연상을 최적화 할수 있다.
아래 예시는 useMemo 를 사용 하지 않았을때 이렇게 사용 하면 input 값이 입력 될때마다 getAverage 실행된다.
import React, { useState} 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("");
const onChange = e => {
setNumber(e.target.value);
};
const onInsert = e => {
const nexList = list.concat(parseInt(number));
setList(nexList);
setNumber("");
};
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<b>평균값:</b>
{getAverage(list)}
</div>
);
};
export default Average;
useMemo 적용 한 예시 적용을 하게 되면 input 에 입력 될시 마다 아니고 값이 새롭게 입력 될떄만 작동하게 됩니다.
이렇게 하게되면 리렌더를 방지 할수있고 효율이 좋아 진다고 생각 하면 될듯 하다.
import React, { 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("");
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []);
const onInsert = useCallback(
e => {
const nexList = list.concat(parseInt(number));
setList(nexList);
setNumber("");
},
[number, list]
);
const avg = useMemo(() => getAverage(list), [list]); //리스트가 변경 될떄만 실행
return (
<div>
<input value={number} onChange={onChange}/>
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<b>평균값:</b>
{avg}
</div>
);
};
- useRef : 컴포넌트에서 ref를 쉽게 사용 할 수 있도록 해주는 hook
import React, { 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("");
const inputEl = useRef(null); //ref 초기값
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []);
const onInsert = useCallback(
e => {
const nexList = list.concat(parseInt(number));
setList(nexList);
setNumber("");
inputEl.current.focus(); //해당 인풋창에 포커싱
},
[number, list]
);
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} ref={inputEl} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<b>평균값:</b>
{avg}
</div>
);
};
export default Average;
간략하게 hooks 기능들을 살펴 봤다 더 자세한 자료를 원한다면 참고 자료 링크를 공유 할테니 참고 해주시면 됩니다.
참고 링크 :
https://nikgraf.github.io/react-hooks/
https://github.com/rehooks/awesome-react-hooks
https://velog.io/@velopert/react-hooks
https://ssangq.netlify.com/posts/react-memo-useMemo-useCallback
'react' 카테고리의 다른 글
7. 라이플 사이클(Life Cycle) 메서드의이해 (0) | 2020.01.22 |
---|---|
2. JSX 란 (0) | 2019.12.03 |
1. 리액트 시작 (0) | 2019.12.03 |