이번 시간에는 state에 대해 더 자세하게 배워보겠습니다.
최종적으로 React에서 사용자들의 input을 어떻게 얻는지, form을 만들었을 때 state는 어떤식으로 작용하는지에 대해 이해해보겠니다. 우선 그 전에 먼저 앱의 state를 바꾸는 법에 대해서 배워보겠습니다.
state를 바꾸는 2가지 방법이 있습니다. (useState를 통해서 얻 array 에서 데이터를 변경하는 함수를 setState라고 하겠습니다.)
첫번째는 setState를 이용해서 state의 값을 직접 변경해주는 것입니다.
setState(counter+1);
setState(9);
setState('lalala');
두번째는 현재 state를 기반으로 계산하고 싶다면 함수를 이용하는 것입니다. setState에 함수를 넣어 이전 state를 이용해서 새로운 state를 생성합니다. 그리고 함수의 return값이 새로운 state가 됩니다.
setState((state) => state+1);
현재 state를 기반으로 계산하고 싶다면 리액트가 현재 state값을 보장하고 있기 때문에 이 방법이 훨씬 안전합니다.
사용자의 input을 어떻게 얻는지, form에서 state는 어떻게 작용하는지 등 state에 대해 더 자세히 이해하기 위해서 '분 단위를 입력했을 때 시간 단위를 알려주는 단위변환기'를 만들어보는 예제를 진행하겠습니다.
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function App () {
// minutes의 값을 input의 value로 넣어주기, input={minutes}
// 사용자가 input에 뭔가를 입력할 때(input에 변화가 생기면), onChange라는 함수 실행
const [minutes, setMinutes] = React.useState()
const onChange = (event) => {
setMinutes(event.target.value);
};
return (
<div>
<h3>Super Converter</h3>
<label htmlFor="minutes">Minutes</label>
<input
value={minutes}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}
/>
<h4>You want to convert {minutes}</h4>
<label htmlFor="hours">Hours</label>
<input id="hours" placeholder="Hours" type="number"/>
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root)
</script>
</html>
결과
1. 사용자가 입력하는 값인 input의 value를 state로 연결
2. onChange함수 -> input에 change 이벤트가 일어났을 때 즉, 사용자가 input에 값을 입력할 때 onChange함수 실행
3. onChange 함수에서 리액트가 제공하는 event.target.value를 통해서 input value를 쉽게 가져온 후 setMinuets함수에서 minutes가 변경될 때마다 새로 update해주고 UI에 자동으로 렌더링 해줌
input의 value를 연결시켜주는 이유는 input값을 외부에서도 수정하기 위해서입니다. 따라서 연결함에 따라 input값을 통제할 수 있고 input값이 변경될때마다 event도 리스닝하고 있습니다.
이번에는 hours도 컨트롤하여 최종적으로 단위변환기를 만들어보겠습니다.
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function App () {
// minutes의 값을 input의 value로 넣어주기, input={minutes}
// 사용자가 input에 뭔가를 입력할 때(input에 변화가 생기면), onChange라는 함수 실행
const [minutes, setMinutes] = React.useState()
const onChange = (event) => {
setMinutes(event.target.value);
};
return (
<div>
<h3>Super Converter</h3>
<div>
<label htmlFor="minutes">Minutes</label>
<input
value={minutes}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}
/>
</div>
<div>
<label htmlFor="hours">Hours</label>
<input
value={minutes/60}
id="hours"
placeholder="Hours"
type="number"
/>
</div>
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root)
</script>
</html>
결과
분 단위를 입력하면 자동으로 시간 단위가 출력됩니다. 리액트에서는 또한 UI가 업데이트 될 때 전부 다 새로 그려지는게 아니라 오직 사용자가 입력하는 value만 리렌더링 되고 있습니다.
Hours input은 onChange 이벤트가 없기 때문에 값을 변경할 수 없습니다. 이번에는 reset버튼을 추가하고 시간 단위도 입력가능하고 입력했을 분 단위로 출력될 수 있도록 해보겠습니다.
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function App () {
// minutes의 값을 input의 value로 넣어주기, input={minutes}
// 사용자가 input에 뭔가를 입력할 때(input에 변화가 생기면), onChange라는 함수 실행
const [amount, setAmount] = React.useState()
const [flipped, setFlipped] = React.useState(false)
const onChange = (event) => {
setAmount(event.target.value);
};
// state를 리스닝하거나 연결된 모든 것들은 0으로 됨
const reset = () => setAmount(0);
//버튼을 눌렀을 때 flip됨, flipped이 false(기본값)라면 분->시간(disabled==true), true면 시간->분(disabled==false)
const onFlip = () => {
reset();
setFlipped(flipped => !flipped );
}
return (
<div>
<h3>Super Converter</h3>
<div>
<label htmlFor="minutes">Minutes</label>
<input
value={flipped ? amount*60 : amount}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}
disabled={flipped}
/>
</div>
<div>
<label htmlFor="hours">Hours</label>
<input
value={flipped ? amount : amount/60}
id="hours"
placeholder="Hours"
type="number"
onChange={onChange}
disabled={!flipped}
/>
</div>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>Flip</button>
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root)
</script>
</html>
결과
따라서 분 -> 시간 변환시켜주고 flip 버튼을 누르면 시간 -> 분으로 변환시켜주는 단위변환기를 만들었습니다.
다음 시간에는 km -> mile로, mile->km로 변환시켜주는 기능까지 추가해보겠습니다.
'프론트엔드 > ReactJS 시작하기' 카테고리의 다른 글
[React] props(2) (0) | 2023.04.11 |
---|---|
[React] props(1) (0) | 2023.04.11 |
[React] state와 useState 이해하기 - 단위변환기(2) (0) | 2023.04.11 |
[React] 리액트 작동원리 이해하기(2) - JSX, state, useState (0) | 2023.04.10 |
[React] 리액트 작동원리 이해하기(1) - JSX (0) | 2023.04.09 |