React와 useState를 사용한 숫자입력기 Sample

(실습 난이도 : 하, 소요시간 : 20min±)
먼저 해당 실습은 React와 useState를 연습하기 위한 단순실습으로
css 디자인이나 대단한코드는 사용되지 않을 것이다.
먼저 Create-React-App으로 React폴더를 생성해보자.
시작하기 앞서 기본셋팅된 값들을 지워주자.
[App.js]
import './App.css';
function App() {
return
}
export default App;
App.js는 이렇게 나머지는 지워주고
App.css와 index.css의 내용들은 전부 지우고 시작한다.
npm start를 했을때 웹에 아무것도 안나와야 정상이다.
첫 실습이니 만큼 쉽고 간단한 계산기를 만들어 보자.
import './App.css';
function App() {
return <div>
<input type="number" value="0"></input>
<button>7</button>
<button>8</button>
<button>9</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>0</button>
</div>
}
export default App;
숫자입력기를 만들것이므로 당연히 숫자입력기를 button으로 생성했다.
그런데 코드가 너무 지저분하다.
React를 사용하는데 Component를 분리하지 않았기 때문이다.
src안쪽에 components라는 폴더를 만들어보자.
그다음 components 안쪽에 Number.js파일을 생성하자.
내용은 App.js에 적었던 내용을 가져와서
function Number() {
return <div>
<input type="number" value="0"></input>
<button>7</button>
<button>8</button>
<button>9</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>0</button>
</div>
}
export default Number;
이렇게 수정해주었다.
그럼 App.js에서 Number.js를 import 해와야 하니 추가해주자.
import './App.css';
import Number from './components/Number';
function App() {
return <Number/>
}
export default App;
여기서 주의할 점은 Components는 가장 앞에있는 알파벳을 대문자로 해야한다.
그런데 Number.js에서 버튼이 너무많다 코드를 줄일 수 없을까?
JavaScript를 안다면 반복문이 떠오를 것이다.
function Number() {
let btnNumber = ["7","8","9","4","5","6","1","2","3","0"];
let btn = null;
for(let i = 0; i < btnNumber.length; i++){
btn = <>{btn}<button>{btnNumber[i]}</button></>
}
return <div>
<input type="number" value="0"></input>
{btn}
</div>
}
export default Number;
이렇게 반복문으로 표현해서 btn이라는 변수에 넣어주고,
이것을 리턴하게 했더니 코드가 깔끔해지고, 다른 버튼을 추가할때 더 간편해졌다.
그럼 기능을 추가해보자.
<input type="number" value="0"></input>
먼저 value의 기본값이 0인데 변수로 선언해주자.
let numberValue = 0;
<input type="text" value={numberValue}></input>
그리고 숫자를 눌렀을때 input박스의 값이 바뀌도록
button을 생성하면서 onClick을 같이 넣어보자.
for(let i = 0; i < btnNumber.length; i++){
btn = <>{btn}<button onClick={()=>{
if(numberValue === 0 || numberValue === "0" && btnNumber[i] === "0"){
numberValue = btnNumber[i];
}else{
numberValue += btnNumber[i];
}
console.log(numberValue);
}}>{btnNumber[i]}</button></>
}
그럼 값이 0일때는 누른 버튼의 값으로 바뀌고
기존 값이 있을때는 기존값 뒤에 누른 값이 추가되도록 작성했다.
또, 값이 0인데 0만 누르게 되면 그대로 0이 되도록 했다.
console.log도 같이 작성해서 테스트해보자.

이상하다 에러도 발생하고 console.log에는 잘 찍히는데
input값이 변경되지 않는다.
에러의 내용을 보니 input의 'onChange handler'를 해야한다고 나온다.
사실 input에서 value를 지정했을때는 값을 변경해도 onChange handler를 해주지 않으면
값이 랜더링 되지 않는다.
이때 onChange handler를 사용하는 방법과 useState를 사용하는 방법이 있는데
useState를 실습해보자.
먼저 useState를 import하자.
import {useState} from 'react';
가장 윗줄에 작성해주면 useState 기능을 사용할 수 있다.
그리고 변수로 선언했던 let calculatorValue = 0;를 변경해주자.
const [numberValue,setNumberValue] = useState("0");
이로써 calculatorValue는 state가 되었다.
그럼 onClick에서 적용되는 명령도 바꿔보자.
for(let i = 0; i < btnNumber.length; i++){
btn = <>{btn}<button onClick={()=>{
if(numberValue === "0"){
setNumberValue(btnNumber[i]);
}else{
setNumberValue(numberValue+btnNumber[i]);
}
}}>{btnNumber[i]}</button></>
}
결과를 확인하니 정상 작동된다.

이는 useState를 실습하기 위해 사용되었으나 에러는 지워지지 않는다.
실제로 사용할 땐 onChange handler를 사용하면 더 좋겠다.
작성이 있으면 삭제도 있어야하는 법
btn = <>{btn}<button onClick={()=>{
if(numberValue.length >= 2){
setNumberValue(numberValue.slice(0,-1));
}else{
setNumberValue("0");
}
}}>지우기</button></>
button을 하나 btn변수에 추가하여 지우기 버튼을 만들어주고 마지막 글자만 삭제하는 방식을 선택했다.
기존의 값이 1자리수만 남았을땐 삭제가 아닌 0으로 되돌리는 방식을 선택했다.
결과물

Code : App.js
import './App.css';
import Number from './components/Number';
function App() {
return <Number/>
}
export default App;
Code : Number.js
import {useState} from 'react';
function Number() {
let btnNumber = ["7","8","9","4","5","6","1","2","3","0"];
let btn = null;
const [numberValue,setNumberValue] = useState("0");
for(let i = 0; i < btnNumber.length; i++){
btn = <>{btn}<button onClick={()=>{
if(numberValue === "0" || numberValue === "0" && btnNumber[i] === "0"){
setNumberValue(btnNumber[i]);
}else{
setNumberValue(numberValue+btnNumber[i]);
}
}}>{btnNumber[i]}</button></>
}
btn = <>{btn}<button className='delete' onClick={()=>{
if(numberValue.length >= 2){
setNumberValue(numberValue.slice(0,-1));
}else{
setNumberValue("0");
}
}}>지우기</button></>
return <div>
<input className='inputBox' type="text" value={numberValue}></input>
<div className='numberPad'>{btn}</div>
</div>
}
export default Number;
이로써 React에, Front-End에 한걸음 내딛었다.
달려보자.