Joon's Space
[React] React Hooks (useState) 1 본문
React Hooks 란?
react의 state machine에 연결하는 기본적인 방법. Hooks를 사용하면 기존의 class 방식을 더 이상 사용하지 않고, 함수형 프로그래밍 방식을 사용한다.
useState
// App.js
import { useState } from "react";
import "./styles.css";
export default function App() {
const [item, setItem] = useState(1); // state 초기값을 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>
);
}
useState는 Array를 return 해야 한다. Array 첫 번째 요소는 item, 두 번째 요소는 setItem.
return 안에 button을 만들어서 onClick={increment}, onClick={decrement} 로 연결해 준다.
만약 hooks를 사용하지 않고 기존처럼 class component 형식으로 작성한다면? 다음과 같이 코드가 길어진다.
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}>Increment</button>
<button onClick={this.decrementItem}>Decrement</button>
</div>
);
}
incrementItem = {
this.setState(state => {
return (
item:state.item + 1
);
});
};
decrementItem = {
this.setState(state => {
return(
item:state.item - 1
);
});
};
}
- useInput
// App.js
import { useState, React } from "react";
import "./styles.css";
const useInput = (initialValue, validator) => {
const [value, setValue] = useState(initialValue);
const onChange = (event) => {
const {
target: { value }
} = event;
setValue(value);
};
return { value, onChange };
};
export default function App() {
const name = useInput("Mr.");
return (
<div className="App">
<h1>Hello</h1>
<input placeholder="Name" {...name} />
</div>
);
}
다음과 같이 initialValue 를 꼭 정해주는 것이 아니라, App function 안에서 useInput을 이용해서 정해 줄 수 있다.
value = {name.value}, onChange = {name.onChange} 부분을 useInput의 return으로 value, onChange 모두 {...name}으로 unpack 할 수 있다.
// App.js
import { useState, React } from "react";
import "./styles.css";
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 };
};
export default function App() {
const maxLen = (value) => value.length < 10;
const name = useInput("Mr.", maxLen); // validator는 maxLen 이다.
return (
<div className="App">
<h1>Hello</h1>
<input placeholder="Name" {...name} />
</div>
);
}
useInput을 정의해줄 때 initialValue 이외 validator라는 function을 parameter로 받아주어 내가 설정한 유효성(검증성)을 확인하게 해주는 기능을 테스트한다. App()에서는 maxLen 함수가 validator가 되어 value.length가 10개 이상이면 willUpdate가 false가 되어 더 이상 value가 변하지 않게 한다.
또한 validator 함수 리턴값에 value.includes를 이용하여 입력에 꼭 필요한 문자, 넣으면 안 되는 문자를 정해 줄 수 있다.
- useTabs
// App.js
import { useState, React } from "react";
import "./styles.css";
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)){ // allTabs가 존재하지 않거나, 배열이 아닌 경우 실패
return;
}
const [currentIndex, setCurrentIndex] = useState(initialTab);
return {
currentItem: allTabs[currentIndex],
changeItem: setCurrentIndex
};
};
export default function App() {
const { currentItem, changeItem } = useTabs(0, content); // 배열의 인덱스 0 부터 시작.
return (
<div className="App">
{content.map((section, index) => (
<button onClick={() => changeItem(index)}>{section.tab}</button>
))}
<div>{currentItem.content}</div>
</div>
);
}
object type인 content를 하나 생성한 뒤, 이것을 control하는 useTabs를 생성해준다.
content는 array이어야 하고, 각 원소들은 object type으로 구성되어 있다. section의 개수만큼 button을 생성해주고, 그 해당하는 버튼을 클릭했을 때(onClick), tabs의 index번호가 클릭한 번호로 set 되게 한다. onClick 괄호 안에는 클릭했을 때 실행되는 함수가 있어야 하는데 ()로 이름 없는 함수가 정의될 수도 있다. ( setCurrentIndex()를 이용한다. )
'Web > React' 카테고리의 다른 글
[React] authentication front-end (log-in, create account, etc) (0) | 2021.07.28 |
---|---|
[TailwindCSS, Apollo GraphQL] frontend setup (0) | 2021.07.26 |
[React] state 변경하기 (bind, setState 함수) (0) | 2021.05.09 |
[React] Component, Props, State (생활코딩) (0) | 2021.05.07 |
[React] 개발 환경 구축하기 (0) | 2021.05.03 |