Front-end
[React Hooks] useState | useInput, useTabs
바닷가쟤
2023. 10. 14. 16:41
ㄴㅁㄷㅋㄷ 무료 강의에 있는 트위터 클론코딩 챌린지를 시작했다!
리액트를 조금 찍먹해보긴 했지만 원래 들었던 리액트 강의에서 기본적인 문법의 쓰임을 알려주지 않아서 ㄴㅁㄷㅋㄷ React Hooks 강의를 빠르게 듣고 트위터 클론코딩 강의를 들으려고 한다.
그래서 ..! #1 USESTATE 까지 듣고 블로그에 기록하면서 공부 내용을 정리해보려 한다 !
useState
컴포넌트에서 바뀌는 값을 관리하기 좋은 useState!
리액트의 기본적인 props .. 개념들을 선행 공부하고 hooks를 배워야 왜 사용하는지, 장점이 뭔지 뼈저리게 느낄 수 있다.
일부러 바닐라 JS로 포켓몬 도감 프로젝트를 만들어서 리액트가 얼마나 편한 도구인지 체감이 된다.
편하게 만든 만큼 왜 어떻게 편해졌고 어땠던 기능을 어떻게 바꿔서 쓰는지 제대로 알아야겠다는 생각이 든다.
state란?
컴포넌트가 가질 수 있는 상태이다.
useState를 사용하기
import { useState } from 'react';
변수 선언
const [state, setState] = useState(초깃값);
변수 재선언
setState(1);
state의 값을 1로 변경한다.
예제
import { useState } from "react";
import "./styles.css";
import ReactDOM from "react-dom";
export default function 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>
);
}
React Hooks
- useTitle
react document의 title을 몇 개의 hooks와 함께 바꾼다.
- useInput
- usePageLeave
유저가 page를 벗어나는 시점을 발견하고 함수를 실행한다.
- useClick
element를 클릭하는 시점을 발견한다.
- useFadeIn
애니메이션을 element 안으로 서서히 사라지게 만든다.
- useFullscreen
어떤 요소든 풀스크린으로 만들거나 일반 화면으로 돌아가게 할 수 있다.
- useHover
마우스를 올렸는지 감지한다.
- useNetwork
Online/Offline 상태인지 감지한다.
- useNotification
notification API를 사용할때 유저에게 알림을 보내준다.
- useScroll
스크롤을 사용할 때 감지한다.
- useTabs
tab을 사용하기 매우 쉽게 만들어준다.
- usePreventLeave
변경사항이나 저장하지 않고 페이지를 벗어나길 원할 때 확인한다.
- useConfirm
위와 비슷한데 추가 기능이 있다.
- useAxios
HTTP requests slient axios를 위한 wrapper 같은 것이다.
useInput
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const useInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
const onChange = (event) => {
console.log(event.target);
};
return { value, onChange };
};
const App = () => {
const name = useInput("Ms.");
return (
<div className="App">
<h1>Hello </h1>
<input placeholder="Name" value={name.value} onChange={name.onChange} />
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
여기 input을 …
<input placeholder="Name" {...name} />
이렇게 바꿔줄 수 있다.
검증
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const useInput = (initialValue, validator) => { // validator는 함수로 들어와야 함
const [value, setValue] = useState(initialValue);
const onChange = (event) => {
const {
target: { value }
} = event;
let willUpdate = true;
if (typeof validator === "function") {
// validator가 함수일 경우 willUpdate에 vaildator(value)를 하고 값이 있으면 true겠죠
// 함수에 의해 true false가 리턴되게 만들 수 있음. 값이 없으면 falsy 데이터니까
willUpdate = validator(value);
}
if (willUpdate) { // willUpdate가 true면 setValue에 value 설정(target.value)
setValue(value);
}
};
return { value, onChange };
};
const App = () => {
const maxLen = (value) => value.length <= 10; // 함수형으로 만듬(validator)
const name = useInput("Ms.", maxLen); // 이렇게 인수 두 개
return (
<div className="App">
<h1>Hello </h1>
<input placeholder="Name" {...name} />
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
useTabs
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 = (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>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
728x90