본문 바로가기

Develop/React

React Hooks

React v16.8에 React Hooks라는 기능이 추가가 되었다. 이 기능은 기존 state 기능을 Functional component에서도 가져다 사용할 수 있는 기능이다.

기본 사용법은 아래와 같다.

import React, { useState } from 'react';

function Example() {
// Declare a new state variable, which we'll call "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를 만들어 해당 클래스 내의 state를 이용해서 구현해주어야 했다. 하지만 새롭게 추가된 Hooks는 간단하게 useState 함수를 이용하여 손쉽게 상태값과 해당 상태값의 setter를 사용할 수 있다.

이러한 예시들은 공식 사이트를 비롯하여 많은 곳에서 많이 볼 수 있다. 여기에 추가적으로 확장에 대해서 한번 알아 보겠다.

Hooks에는 Custom hook이라 하여 기본 존재하는 hook 기능을 임의로 확장하여서 사용할 수 있다.

const useInput = defaultValue => {
const [value, setValue] = useState(defaultValue);

const onChange = e => {
const {
target: { value },
} = e;

setValue(value);
};

return { value, onChange };
};
const App = () => {
const nameInput = useInput("");
const yourNameInput = useInput("");
return (
<div>
<h1>Use Hooks</h1>
<br />
<input {...nameInput} placeholder="MyName" />
<input {...yourNameInput} placeholder="YourName" />
</div>
);
}

useInput은 useState를 확장하여 input name과 yourName 인풋을 만들었다. 아주 손쉽게 두개의 input state와 각각의 onChage 핸들러가 만들어졌다.

axios를 사용한 fetch hook도 만들어 줄 수 있다.

const useFetch = () => {
const [payload, setPayload] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");

const doFetch = async (url) => {
try {
const { data } = await axios.get(url);
setPayload(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};

return { doFetch, error, loading, payload };
};

const App = () => {
const { payload, loading, error } = useFetch();

useEffect(() => {
doFetch("url/to/get/data");
}, []);

return (
<div>
<h1>Use Hooks</h1>
{loading && <span>Loading...</span>}
{!loading && error && <span>Error: {error}</span>}
{!loading && !error && payload && <h2>{payload.file}</h2>}
</div>
);
}

간단하게 fetch hook을 만들었다. 이를통해 언제든지 axios를 사용해 데이터를 긁어올때 loading, error, payload를 귀찮게 별도로 만들어 줄 필요가 없어졌다.

useEffect도 react hooks 기능에 추가되었는데, 이는 기존에 componentDidMount, componentDidUpdate 등의 함수와 같은 역할을 수행한다. 여기서는 componentDidMount의 역할을 수행하게 하였다.

즉, Class Component가 아닌 Functional Component를 사용하여도 얼마든지 State를 사용하여 개발이 가능하게 되었다는 뜻이다.

여기에 더해 Apollo를 사용하면서 Query, Mutation이 많아지면서 소스코드가 많이 복잡해졌는데, react-apollo-hooks 라는 모듈을 사용해주면 react hooks처럼 깔끔하게 개발이 가능할 것같다.