프로젝트를 마치고 Hooks에 대해서 좀 더 공부해보고 싶어서 이런 저런 자료를 찾아보며 공부 중에 있다.
해당 내용에 대한 이해도가 높아진다면 프로젝트에 공통적인 부분을 Hooks로 만들어서 적용해볼 예정이다.
일단 useState를 활용한 Hooks를 공부해보았다.
const useInput = (initialValue, validation) => {
const [value, setValue] = useState(initialValue);
const onChange = (e) => {
const { value } = e.target;
if (typeof validation === "function") {
validation(value);
}
if (validation(value)) {
setValue(value);
}
};
return { value, onChange };
};
const App = () => {
const validate = value => value.length <= 10;
const {value, onChange} = useInput("Mr.", validate);
return (
<div>
<input value={value} onChange={onChange}/>
</div>
);
};
input의 입력값에 대한 검증을 하는 Hooks이다.
위의 경우는 input의 value값의 길이가 10이 넘으면 if(validation(value))
의 값이 false가 되어서 더이상 setValue가 동작하지 않는다.
위 처럼 길이에 대한 조건으로 hooks를 만들수도 있지만 본인이 원하는 검증 방식으로도 커스터마이징 해볼수 있다.
const content = [
{
tab: "Section 1",
content: "I'm the content of section 1"
},
{
tab: "Section 2",
content: "I'm the content of section 2"
}
];
const useTabs = (initialTab, content) => {
const [currentIndex, setCurrentIndex] = useState(initialTab);
if (!content || !Array.isArray(content)) {
return;
}
const handleOnClick = (index) => {
setCurrentIndex(index);
};
return { currentIndex, handleOnClick };
};
const App = () => {
const { currentIndex, handleOnClick } = useTabs(0, content);
return (
<div className="App">
{content.map((data, index) => {
return (
<button key={index} onClick={() => handleOnClick(index)}>
{data.tab}
</button>
);
})}
{content[currentIndex].content}
</div>
);
};
이 useTabs는 프로젝트할 때 적용해보았으면 정말 좋았을 hooks이다.
프로젝트의 상단 메뉴에 탭이 여러개 있는데, useTabs의 default value로 0을 주면 처음 웹페이지에 접속할 때 rendering이 되면서 0번째에 있는 tab이 선택되고 다른 탭을 눌렀을 때 <button key={index} onClick={() => handleOnClick(index)}>
의 onClick 이벤트를 통해 내가 클릭한 탭의 index
값을 넘겨주면서 탭 전환이 이루어질수 있도록 한다.
const useTitle = (initialTitle) => {
const [title, setTitle] = useState(initialTitle);
const changeTitle = () => {
const titleChange = document.querySelector("title");
titleChange.innerText = title;
};
useEffect(changeTitle, [title]);
return setTitle;
};
const App = () => {
const setTitle = useTitle("Loading");
setTimeout(() => {
setTitle("Done");
}, 2000);
return (
<div className="App">
<h1>Hi</h1>
</div>
);
};