- npm 공식 페이지
npm | build amazing things
Build amazing things We're npm, Inc., the company behind Node package manager, the npm Registry, and npm CLI. We offer those to the community for free, but our day job is building and selling useful tools for developers like you. Take your JavaScript devel
www.npmjs.com
nomadcoders.co/react-hooks-introduction/lectures/1714
- React Hook 관련 강의
haeguri.github.io/2019/10/13/react-hooks-basic/
- React Hooks에 대하여.
React Hooks 살펴보기 · Devlog
Hooks를 공부하기 위해서 공식 문서를 읽으면서 개인적으로 정리한 내용입니다. 정리하는 과정에서 내용이 생략되거나 추가된 내용이 있을 수 있습니다. 리액트 Hooks는 16.8.0에서 새로 도입된 기
haeguri.github.io
github.com/kr-MATAGI/React-Study
- Repository
> Reack Hook ?
- React v16.8 에 새로 도입된 기능.
- 함수형 컴포넌트에서도 상태 관리를 할 수 있는 useState,
렌더링 직후 작업을 설정하는 useEffect 등의 기능 등을 제공하여 기존의 함수형 컴포넌트에서
할 수 없었던 다양한 작업을 할 수 있게 해준다.
1. useState
- 기존에 class component에서 사용하던 render(), this.setState 코드를 획기적으로 줄이고
함수형 프로그래밍 언어로써 코드를 작성할 수 있다.
class AppUgly extends React.Component {
state = {
item: 1
};
render() {
const { item } = this.state;
return (
<div className="App">
<h1>Hello {item}</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={this.incrementItem}>Increse</button>
<button onClick={this.decreasementItem}>descrese</button>
</div>
);
}
incrementItem = () => {
this.setState((state) => {
return {
item: state.item + 1
};
});
};
decreasementItem = () => {
this.setState((state) => {
return {
item: state.item - 1
};
});
};
}
- Reack Hooks (useState)
const App = () => {
const [item, setItem] = useState(1);
const incrementItem = () => setItem(item + 1);
const decreasementItem = () => setItem(item - 1);
return (
<div className="App">
<h1>Hello {item}</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={incrementItem}>Increse</button>
<button onClick={decreasementItem}>descrese</button>
</div>
);
};
1.1 useInput - input에 대한 동작을 함수형 컴포넌트로 제어할 수 있다.

import React, { useState } from "react";
import ReactDOM from "react-dom";
const useInput = (initValue, validator) => {
const [value, setValue] = useState(initValue);
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>
);
};
export default App;
1.2 useTabs
- onClick -> chagneItem -> setCurrIndex 변경 -> useState() -> changeState -> currItem의 currentIndex 변경
import React, { useState } from "react";
import ReactDOM from "react-dom";
const content = [
{
tab: "Section 1",
content: "I'm the content of the section 1"
},
{
tab: "Section 2",
content: "I'm the content of the section 2"
}
];
const useTabs = (initTab, allTabs) => {
if (!allTabs || !Array.isArray(allTabs)) return;
const [currentIdx, setCurrIndex] = useState(initTab);
return {
currItem: allTabs[currentIdx],
changeItem: setCurrIndex
};
};
const App = () => {
const { currItem, changeItem } = useTabs(0, content);
return (
<div className="App">
{content.map((section, index) => (
<button onClick={() => changeItem(index)}>{section.tab}</button>
))}
<div>{currItem.content}</div>
</div>
);
};
export default App;
2. useEffect
- componentDidMount, componentDidUnMount, componentWillUpdate 역할을 한다고 생각하면 된다.
- useEffect() 내에 함수를 넣으면 componentDidMount, componentDidUnMount 에서 호출된다. (defendency 없을때)
만약 defendency가 있다면 componentDidMount일 때 호출된다.
- function return은 componentDidUnmount()에서 호출된다.
import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
const App = () => {
const sayHello = () => console.log("hello");
const [number, setNumber] = useState(0);
const [aNumber, setAnumber] = useState(0);
// componentDidMount, componentWiilUpdate
useEffect(sayHello, [number]);
return (
<div className="App">
<div>Hi</div>
<button onClick={() => setNumber(number + 1)}>{number}</button>
<button onClick={() => setAnumber(aNumber + 1)}>{aNumber}</button>
</div>
);
};
export default App;
2.1 useTitle
- setTimeout() 에 의해 5 초뒤 Loading... -> Home 으로 Title이 업데이트.
import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
const useTitle = (initialTitle) => {
const [title, setTitle] = useState(initialTitle);
const updateTitle = () => {
const htmlTitle = document.querySelector("title");
htmlTitle.innerText = title;
};
useEffect(updateTitle, [updateTitle]);
return setTitle;
};
const App = () => {
const titileUpdater = useTitle("Loading...");
setTimeout(() => {
titileUpdater("Home");
}, 5000);
return (
<div className="App">
<div>Hi</div>
</div>
);
};
export default App;
3. useRef()
- reference 참조하기 위함.
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const App = () => {
const input = useRef();
console.log(input.current);
return (
<div className="App">
<div>Hi</div>
<input ref={input} placeholder="la" />
</div>
);
};
export default App;

3.1 useClick()
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useClick = (onClick) => {
if (typeof onclick !== "function") return;
const element = useRef();
useEffect(() => {
if (element.current) {
element.current.addEventListener("click", onClick);
}
return () => {
if (element.current) {
element.current.removeEventListener("click", onClick);
}
};
}, []);
return element;
};
const App = () => {
const sayHello = () => console.log("say Hello");
const title = useClick(sayHello);
return (
<div className="App">
<h1 ref={title}>Hi</h1>
</div>
);
};
export default App;
4. useConfirm
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useConfirm = (msg, confirmCallback, abortedCallback) => {
if (!confirmCallback && typeof confirmCallback !== "function") return;
if (!abortedCallback && typeof abortedCallback !== "function") return;
const confirmAction = () => {
if (confirm(msg)) {
confirmCallback();
} else {
abortedCallback();
}
};
return confirmAction;
};
const App = () => {
const deleteWorld = () => {
console.log("Deleting the world...");
};
const abort = () => {
console.log("Aborted");
};
const confirmDelete = useConfirm("Are you sure?", deleteWorld, abort);
return (
<div className="App">
<h1>Hello</h1>
<button onClick={confirmDelete}>Delet the world</button>
</div>
);
};
export default App;
5. usePreventLeave
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
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">
<h1>Hello</h1>
<button onClick={enablePrevent}>protect</button>
<button onClick={disablePrevent}>unProtect</button>
</div>
);
};
export default App;
6. useBeforeLeave
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useBeforeLeave = (onBefore) => {
if (!onBefore && typeof onBefore !== "function") return;
const handle = (event) => {
const { clientY } = event;
if (0 >= clientY) {
onBefore();
}
};
useEffect(() => {
document.addEventListener("mouseleave", handle);
return () => document.removeEventListener("mouseleave", handle);
}, []);
};
const App = () => {
const begForLife = () => console.log("Plz dont leave");
useBeforeLeave(begForLife);
return (
<div className="App">
<h1>Hello</h1>
</div>
);
};
export default App;
7. useFadeIn
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useFadeIn = (duration = 1, delay = 0) => {
if (typeof duration !== "number" || typeof delay !== "number") return;
const element = useRef();
if(!element) return;
useEffect(() => {
if (element.current) {
const { current } = element;
current.style.transition = "opacity ${duration}s ease-in-out ${delay}s";
current.style.opacity = 1;
}
}, [duration, delay]);
return { ref: element, style: { opacity: 0 } };
};
const App = () => {
const fadeInH1 = useFadeIn(1, 2);
const fadeInP = useFadeIn(5, 10);
return (
<div className="App">
<h1 {...fadeInH1}>Hello</h1>
<p {...fadeInP}>p text</p>
</div>
);
};
export default App;
8. useNetwork
import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
const useNetwork = (onChange) => {
const [status, setStatus] = useState(navigator.online);
const handleChange = () => {
if (typeof onChange === 'function') {
onChange(navigator.online);
}
setStatus(navigator.online);
};
useEffect(() => {
window.addEventListener("online", handleChange);
window.addEventListener("offline", handleChange);
return () => {
window.removeEventListener("online", handleChange);
window.removeEventListener("offline", handleChange);
};
}, []);
return status;
};
const App = () => {
const handleNetworkChage = online => {
console.log(online ? "online" : "offline");
};
var online = useNetwork(handleNetworkChage);
return (
<div className="App">
<h1>{online ? "Online" : "Offline"}</h1>
</div>
);
};
export default App;
9. useScroll
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useScroll = () => {
const [state, setState] = useState({
x: 0,
y: 0
});
const onScroll = () => {
setState({
x: window.scrollX,
y: window.scrollY
});
};
useEffect(() => {
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
return state;
};
const App = () => {
const { y } = useScroll();
return (
<div className="App" style={{ height: "1000vh" }}>
<h1 style={{ position: "fixed", color: y > 100 ? "red" : "blue" }}>Hi</h1>
</div>
);
};
export default App;
10. useFullScreen
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useFullScreen = (callback) => {
const element = useRef();
const triggerFull = () => {
if (element.current) {
element.current.requestFullscreen();
if (callback && typeof callback === "function") {
callback(true);
}
}
};
const exitFullScreen = () => {
document.exitFullscreen();
if (callback && typeof callback === "function") {
callback(false);
}
};
return { element, triggerFull, exitFullScreen };
};
const App = () => {
const onFulls = (isFull) => {
console.log(isFull ? "Full" : "Small");
};
const { element, triggerFull, exitFullScreen } = useFullScreen(onFulls);
return (
<div className="App">
<div ref={element}>
<img src="data:image/jpeg;base64,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" />
<p>
<button onClick={triggerFull}>Make fullscreen</button>
<button onClick={exitFullScreen}>Exit fullscreen</button>
</p>
</div>
</div>
);
};
export default App;
11. useNotification
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const useNotification = (title, options) => {
if (!("Notification" in window)) return;
const fireNotif = () => {
if (Notification.permission !== "granted") {
Notification.requestPermission().then((permission) => {
if (permission === "granted") new Notification(title, options);
else return;
});
} else {
new Notification(title, options);
}
};
return fireNotif;
};
const App = () => {
const tirggerNotif = useNotification("Say Hello !", { body: "Matagi" });
return (
<div className="App">
<button onClick={tirggerNotif}>Hello</button>
</div>
);
};
export default App;
12. useAxios
// App.js
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
import useAxios from "./useAxos";
const App = () => {
const { loading, data, error, refetch } = useAxios({
url: "https://yts-proxy.nomadcoders1.now.sh/list_movies.json?sort_by=rating"
});
console.log(JSON.stringify(data));
return (
<div className="App">
<h1>{data && data.status}</h1>
<h2>{loading && "Loading"}</h2>
<button onClick={refetch}>refetch</button>
</div>
);
};
export default App;
// useAxios.js
import defaultAxios from "axios";
import { useEffect, useState } from "react";
const useAxios = (options, axiosIns = defaultAxios) => {
const [state, setState] = useState({
loading: true,
error: null,
data: null
});
const [trigger, setTrigger] = useState(0);
if (!options.url) {
return;
}
const refetch = () => {
setState({
...state,
loading: true
});
setTrigger(Date.now());
};
useEffect(() => {
axiosIns(options)
.then((data) => {
setState({
...state,
loading: false,
data
});
})
.catch((error) => {
setState({
...state,
loading: false,
error
});
});
}, [trigger]);
return { ...state, refetch };
};
export default useAxios;
'Language > React.js' 카테고리의 다른 글
[React] Ubuntu에서 npm global 패키지 설치 시 오류 (0) | 2021.03.03 |
---|---|
[React] NPM과 NPX, package-lock.json (0) | 2021.01.27 |
[React] JavaScript / React Binding (0) | 2021.01.24 |
[React] React Event (0) | 2021.01.24 |
[React] React 수명주기(Lifecycle) (0) | 2021.01.24 |