(오..npm에 본인들이 만든 hooks을 공유하는 개발자들이 굉장히 많다..
영상에서 니꼬쌤도 실제로 npm에 자신이 만들어 쓰는 hooks을 공유할거라고 했고, 나도 npm upload를 해보고싶다.)
https://nomadcoders.co/react-hooks-introduction/lectures/1586
All Courses – 노마드 코더 Nomad Coders
초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!
nomadcoders.co
저번에 노마드코더의 리액트 기초와 NextJS를 완강했으니 이번엔 실전형 리액트 Hooks 에 대해 들어보고자 한다.
이것도 역시 무료강의.
code sendbox 에서 실습
useState
const [item, setItem] = useState(1); //명시
<h1> { item } </h1> //사용
hooks이 나오기 전에는 this. 나 return 등으로 사용했었는데 hooks 이 나오고는 그런거 신경 안써줘도됨!
const App = () => {
const [item, setItem] = useState(1);
const incrementItem = () => setItem(item + 1);
const decrementItem = () => setItem(item - 1);
return (
<div className = "App">
<h1>Hello {item}</h1>
<h2>Start editing to see some magic happen !</h2>
<button onClick={incrementItem}>Increment</button>
<button onClick={decrementItem}>Decrement</button>
</div>
);
}
useInput
기본적으로 input을 변경.
const useInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
const onChange = event => {
console.log(event.target);
}
return { value, onChange };
};
const App = () => {
const name = useInput("Mr.");
return (
<div className="App">
<h1>Hello</h1>
<input placeholder="Name" {...name}/>
</div>
);
}
요기에 validation 코드 넣어보기 => value의 길이 제한 해보기
const useInput = (initialValue, validator) => {
const [value, setValue] = useState(initialValue);
const onChange = event => {
const {
target : { value }
} = event;
let willUpdate = true;
if(typeof validator === "function"){
willUpdate = validator(value);
}
if(willUpdate){
setValue(value);
}
}
return { value, onChange };
};
const App = () => {
const maxLen = (value) => value.length < 10;
const name = useInput("Mr." , maxLen);
return (
<div className="App">
<h1>Hello</h1>
<input placeholder="Name" {...name}/>
</div>
);
}
useTabs
const content = [
{
tab : "section 1",
content : "I am the content of the Section 1"
},
{
tab : "section 2",
content : "I am the content of the Section 2"
}
]
const useTabs = (initialTab, allTabs) => {
if(!allTabs || !Array.isArray(allTabs)){//예외처리
return;
}
const [currentIndex, setCurrentIndex] = useState(initialTab);
return {
currentItem : allTabs[currentIndex],
changeItem : setCurrentIndex
};
};
const App = () => {
const {currentItem, changeItem} = useTabs(0, content);
return(
<div className = "App">
{content.map({section, index} => (
<button onClick={() => changeItem(index)}>
{section.tab}
</button>
))}
<div<{currentItem.content}</div>
</div>
);
}
useEffect
기존 componentDidMount, componentDidUpdate, componentWillUnMount 역할 수행
useEffect(함수, [ dependency] );//dependency 가 바뀔때마다 실행.
한번만 실행 시키고 싶다면
useEffect(함수, [ ] ); //dependency 비워놓으면 됨.
useTitle
제목을 업데이트 하는 hooks 만들어보기
const useTitle = (initialTitle) => {
const [title, setTitle] = useState(initialTitle);
const updateTitle = () => {
const htmlTitle = document.querySelector("title");
htmlTitle.innerText = title;
}
useEffect(updateTitle, [title]);
return setTitle;
}
const App - () => {
const titleUpdater = useTitle("Loading...");
setTimeout(() => titleUpdater("Home"), 3000); //3초뒤에 타이틀 바뀌도록 테스트코드넣음.
return (
<div className = "App">
<div>Hi...</div<
</div>
);
};
useClick
reference는 기본적으로 component의 어떤 부분을 선택할 수 있는 방법.
( document.getElementById()를 사용한것과 동등 )
//useRef() 사용예제.
const App = () => {
const potato = useRef();
setTimeout(() => potato.current.focus().3000);//3초뒤에 포커싱.
return(
<div className="App">
<div>Hi</div>
<input ref={potato} placeholder="test"/>
</div>
);
}
//useClick() 사용예제.
const useClick = onClick => {
if(typeof onClick !== "function"){
return;
}
const element = useRef();
useEffect(() => {
if(element.current) {//존재여부확인
element.current.addEventListener("click", onClick);
}
return () => {//componentWillUnMount 때 호출.
if(element.current) {
element.curren.removeEventListener("click", onClick);
}
};
}, []);//dependency 없음. componentDidMount 때 한번만 실행되라는 의미.
return element;
}
const App = () => {
const sayHello = () => console.log("say hello");
const title = useClick();
return(
<div className="App">
<h1 ref={title}>Hi</h1>
</div>
);
}
useConfirm & usePreventLeave
//useConfirm : 사용자가 무엇을 하기 전에 확인.
const useConfirm = (message = "", onConfirm, onCancel) => {
if(!onConfirm && typeof onConfirm !== "function ") {//onConfirm 함수가 명시되어있지않거나, 함수가 아닐때
return;
}
if(!onCancel && typeof onCancel !== "function ") {
return;
}
const confirmAction = () => {
if(confirm(message)){
onConfirm();
} else {
onCancel();
}
};
return confirmActions;
};
const App = () => {
const del = () => console.log("Delete");
const abort = () => console.log("Aborted");
const confirmDelete = useConfirm("Are you sure?", del, abort);
return (
<div className = "App">
<button onClick={confirmDelete}>Delete</button>
</div>
);
};
//usePreventLeave
const usePreventLeave = () => {
const listener = (event) => {
event.preventDefault();
event.returnValue = "";
}
const enablePrevent = () => window.addEventListener("beforeunload", listener);
const disablePrevent = () =>
window.removeEventListener("beforeunload", listener);
return {enablePrevent, disablePrevent};
}
const App = () => {
const [enablePrevent, disablePrevent] = usePreventLeave();
return (
<div className="App">
<button onClick={enablePrevent}>Protect</button>
<button onClick={disablePrevent}>UnProtect</button>
</div>
);
};
useBeforeLeave
탭을 닫을 때 실행되는 function
const useBeforeLeave = (onBefore) => {
if(typeof onBefore !== "function"){
return;
}
const handle = (event) => {
const {clientY} = event;
if(clientY <= 0) {
onBefore();
}
}
useEffect(() => {
document.addEventListener("mouseleave", handle);//component가 Mount 되었을때
return () => document.removeEventListener("mouseleave", handle);//component가 Mount되지 않았을때
}, []);
};
const App = () => {
const begForLife = () => console.log("Pls don't leave");
useBeforeLeave(begForLife);
return(
<div className="App">
<h1>Hello</h1>
</div>
);
};
useNotification
브라우저 알람 실행하는 api 가져와 써보기
notificaton API
const useNotification = (title, optons) => {
if(!("Notification" in window)){
return;
}
const fireNotif = () => {
if(Notificaton.permission !== "granted"){
Notificaton.requestPermission().then(permission => {
if(permission === "granted"){
new Notification(title, options);
} else {
return;
}
});
} else {
new Notification(title, options);
}
};
return fireNotif;
};
cosnt App = () => {
const triggerNotif = useNotification("Hello World!", {body : "Welcome"});
return(
<div>
<button onClick={triggerNotif}>Noti</button>
</div>
);
};
useAxios
axios : HTTP request를 만들때 씀.
axios를 add dependency 해줌.(npm 설치와 비슷)
//useAxios.js
import defaultAxios from "axios";
const useAxios = (opts, axiosInstance = defaultAxios) => {
const [state, setState] = useState({
loading : true,
error : null,
data : null
});
const [trigger, setTrigger] = useState(0);
if(!opts.url) {
return;
}
const refetch = () => {
setState({
...state,
loading : true
});
setTrigger(Date.now());
}
useEffect(() => {//trigger 버튼 누를때마다 refetch하도록 구현
axiosInstance(opts).then(response => {
setState({
...state,
loading : false,
data
});
}).catch(error => {
setState({...state, loading : false, error});
});
}, [trigger]);
return {...state, refetch};
};
export default useAxios;
//index.js
...
const App = () => {
const { loading, data, refetch } = useAxios({url : "https"://어쩌고"});
console.log(`Loading : ${loading}\nError : ${error}\nData : ${JSON.stringfy(data)}`);
return(
<div>
<h1>{data && data.status}</h1>
<h2>{loading && "Loading"}</h2>
<button onClick={refetch}>
Refetch
</button>
</div>
);
}
...
'스터디 > React' 카테고리의 다른 글
[Next.js] render 가 두번씩 되는 현상. (0) | 2022.06.20 |
---|---|
[prisma] next 프레임워크에 prisma 연동해보기 (풀쿼리) (0) | 2022.05.19 |
[Next.js]노마드코더 NextJS 시작하기 강의 (0) | 2022.05.11 |
[SSR/CSR] 빠른 view를 위하여 (0) | 2022.05.10 |
[노마드코더 ReactJS] React JS 로 영화 웹서비스 만들기 (0) | 2022.05.04 |