1. Custom Hook의 예시
- 여러 input 상태 변경을 할 때 쓸 수 있는
useInput
Hook이다.
import { useState, useCallback } from 'react';
function useInput(initialForm) {
const [form, setForm] = useState(initialForm);
const onChange = useCallback(e => {
const { name, value } = e.target;
setForm(form => ({ ...form, [name]: value }));
}, []);
const reset = useCallback(() => setForm(initialForm), [initialForm]);
return [form, onChange, reset];
}
export default useInput;
- 기존의 App.js에서 input 부분을 커스텀 훅으로 따로 분리한 후, input 요소도 별도의 컴포넌트로 분리했다.
import { useState } from "react";
import "./styles.css";
export default function App() {
const [firstNameValue, setFirstNameValue] = useState("");
const [lastNameValue, setLastNameValue] = useState("");
const [nameArr, setNameArr] = useState([]);
const handleSubmit = (e) => {
e.preventDefault();
setNameArr([...nameArr, `${firstNameValue} ${lastNameValue}`]);
};
return (
<div className="App">
<h1>Name List</h1>
<div className="name-form">
<form onSubmit={handleSubmit}>
<div className="name-input">
<label>성</label>
<input
value={firstNameValue}
onChange={(e) => setFirstNameValue(e.target.value)}
type="text"
/>
</div>
<div className="name-input">
<label>이름</label>
<input
value={lastNameValue}
onChange={(e) => setLastNameValue(e.target.value)}
type="text"
/>
</div>
<button>제출</button>
</form>
</div>
<div className="name-list-wrap">
<div className="name-list">
{nameArr.map((el, idx) => {
return <p key={idx}>{el}</p>;
})}
</div>
</div>
</div>
);
}
import useInput from "./util/useInput";
import Input from "./component/Input";
import "./styles.css";
import { useState } from "react";
export default function App() {
const [firstInputValue, firstHandleChange, firstReset] = useInput('');
const [lastInputValue, lastHandleChange, secondReset] = useInput('');
const [nameArr, setNameArr] = useState([]);
const handleSubmit = (e) => {
e.preventDefault();
setNameArr([...nameArr, `${firstInputValue} ${lastInputValue}`]);
firstReset();
secondReset();
}
return (
<div className="App">
<h1>Name List</h1>
<div className="name-form">
<form onSubmit={handleSubmit}>
<Input labelText={'성'} value={firstInputValue} handleChange={firstHandleChange} />
<Input labelText={'이름'} value={lastInputValue} handleChange={lastHandleChange} />
<button>제출</button>
</form>
</div>
<div className="name-list-wrap">
<div className="name-list">
{nameArr.map((el, idx) => {
return <p key={idx}>{el}</p>;
})}
</div>
</div>
</div>
);
}
import { useState } from "react";
function useInput(initialValue, initialArr) {
const [inputValue, setInputValue] = useState(initialValue);
const handleChange = (e) => {
setInputValue(e.target.value);
}
const reset = () => {
setInputValue(initialValue);
}
return [inputValue, handleChange, reset];
}
export default useInput;
function Input({ labelText, value, handleChange }) {
return (
<div className="name-input">
<label>{labelText}</label>
<input
value={value}
onChange={handleChange}
type="text"
/>
</div>
)
}
export default Input;
2) useFetch
- 여러 url을 fetch할 때 쓸 수 있는
useFetch
Hook이다.
const useFetch = (initialUrl: string) => {
const [url, setUrl] = useState(initialUrl);
const [value, setValue] = useState('');
const fetchData = () => axios.get(url).then(({ data }) => setValue(data));
useEffect(() => {
fetchData();
}, [url]);
return [value];
};
export default useFetch;
- 기존의 App.js에서 fetch 부분을 커스텀 훅으로 따로 분리했다.
import "./styles.css";
import { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState();
useEffect(() => {
fetch("data.json", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then((response) => {
return response.json();
})
.then((myJson) => {
setData(myJson);
})
.catch((error) => {
console.log(error);
});
}, []);
return (
<div className="App">
<h1>To do List</h1>
<div className="todo-list">
{data &&
data.todo.map((el) => {
return <li key={el.id}>{el.todo}</li>;
})}
</div>
</div>
);
}
import "./styles.css";
import useFetch from "./util/hooks";
export default function App() {
const data = useFetch('data.json')
return (
<div className="App">
<h1>To do List</h1>
<div className="todo-list">
{data &&
data.todo.map((el) => {
return <li key={el.id}>{el.todo}</li>;
})}
</div>
</div>
);
}
import { useState, useEffect } from "react";
const useFetch = (fetchUrl) => {
const [data, setData] = useState(null);
useEffect(() => {
fetch(fetchUrl, {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then((response) => {
return response.json();
})
.then((myJson) => {
setData(myJson);
})
.catch((error) => {
console.log(error);
});
}, [fetchUrl]);
return data;
};
export default useFetch;