계산기 실습

#CSS #React

계산기 만들기 실습 예제가 있어, 예제 코드를 확인하기 전 먼저 코드를 짜보고 예제와 비교해보았다. 계산기는 간단한 사칙연산이 가능한 웹 계산기로, 샘플은 아래와 같다.

그리고 이건 내가 만든 계산기다.

자습서의 흑백 사진을 보고 만들었더니 색상이 많이 다르다.🤔

JSX 코드 비교

컴포넌트

나는 컴포넌트를 두 개 추가했다. 하나는 숫자 버튼과 소수점 버튼에 대응하는 ‘NumberButton’이고, 다른 하나는 사칙 연산자 버튼에 대응하는 ‘SignButton’이다.

예제 코드에서는 따로 컴포넌트 추가는 없었다.

스타일링

나는 이번에 스타일을 적용할 때 vanila-extract를 한 번 사용해보았다. 클래스는 container, inputStyle, smallButton, bigButton, red, darkGrey 6개로 나누어 조합해서 사용했는데, 사용하기에 나쁘지 않았다. 특히 classnames를 사용해서 클래스 이름을 편하게 조합할 수 있는게 좋았다. 내부 코드는 내가 아는 css 속성인 backgroundColor, width, height, flex를 조합해서 구현했다. 프레임워크 라이브러리를 쓰지 않고 css를 사용하는게 거의 처음이라 쉽지 않았다.

예제 코드에서는 전통 스타일 방식을 사용해 .css 파일에 글로벌 방식으로 스타일을 선언했다. 여기서 특히 달랐던 점은 버튼의 크기를 지정하는 방식이였다. 나는 버튼의 크기를 픽셀 크기를 지정해서 차이를 둔 반면, 예제에서는 grid을 사용하여 크기를 지정했다. gird-template-columns: repeat(4, 65px)로 적용하니 자동적으로 작은 버튼이 4개 일렬로 배치된 후 다음 줄로 내려갔는데, 나는 이 속성을 몰라 JSX에서는 div 그룹으로 컴포넌트들을 한 번 묶었고, flex 속성을 사용해서 행을 바꿨다. 찾아보니 계산기처럼 격자무늬가 명확한 UI는 CSS Grid가 정석이라고 한다. grid-column를 쓰면 ’=’ 버튼처럼 두 칸을 차지하는 버튼도 훨씬 쉽게 배치할 수 있다.

로직 비교

자료구조

나는 useState를 두 개 추가했다. 하나는 현재의 값을 저장하는 string이고, 다른 하나는 calculate 하기 전 까지의 값을 차례대로 저장해두는 array다. 현재의 값을 보여주는 value은 input 태그와 연결해 사용자의 인터렉션에 따라 바로 화면에 나타나게했고, array는 내부에서만 사용했다. (이렇게 정리해보니 내부에서만 사용하는 array는 useState로 지정하지 않았어도 되었을 것 같다.)

예제는 하나의 객체를 useState로 추가했다. 객체 안에는 현재의 숫자를 저장하는 string, 이전의 숫자를 저장하는 string, 현재 연산자를 저장하는 string, 지금 입력한 것이 새로운 숫자인지 파악하는 boolean 총 4가지 상태가 있었다. 상태가 여러개인 경우는 하나의 객체로 관리하는 것이 확실히 더 좋은 것 같다.

로직

자료구조를 보자마자 생각했지만 로직이 서로 너무 달라서 비교가 어려웠다. 이 부분은 Gemini의 도움을 받아 정리했다.

예제는 상태 머신 방식에 가깝게 설계되어있는 코드라고 한다. 내가 이해한 상태 머신 방식은 상태를 자료에 저장해두고, 어떤 메서드가 실행될 때마다 상태를 체크해서 로직을 실행한 뒤 다른 상태로 이동하는 것이다. 그래서 예제의 각 로직을 보면 if 문을 이용해 현재 계산기의 상태(현재 숫자, 이전 숫자, 현재 연산자, 신규 숫자 여부)를 파악하고, 그에 따라 로직을 실행한 뒤 다음 상태로 업데이트 하는 것을 확인할 수 있다. 처음에는 if문이 많아서 코드 파악이 어렵다고 생각했는데 이해하고나니 오히려 단순했다.

내 로직에서 핵심이 되는 부분은 2씩 건너 뛰는 반복문이라고 생각하는데, 이 코드를 구성할 때 많은 시행착오를 거쳤다. for문 i의 값마다 내부 변수 값이 어떻게 변하는지 일일이 파악하면서 작성하는 것이 어려웠기 때문이다. 바로 수학적 로직이 튀어나왔다면 내가 구현한 코드도 장점이 있다고 생각하지만 시간이 오래걸린 것이 아쉽다.

결론

리액트를 처음 배운 뒤 만들어본 첫 앱이라 의미가 있었고, 예제 코드와의 비교에서는 레이아웃 스타일링과 상태 설계 측면에서 배울 점이 많았다. 레이아웃 스타일링상태 설계 패턴을 추가로 공부해 두어야겠다.

내가 짠 코드: https://github.com/umnoni/react_calculator