3일간의 미니프로젝트 - 105+1 탄핵타자연습

created:
last-updated:

12/14 탄핵 표결 전 완성하기 위해 3일동안 부리나케 만들어 본 미니 프로젝트 105+1 탄핵 타자 연습을 공유합니다. 국회앞 인파 속 데이터가 터지지 않아 탄핵 가결 후 올리게 됐지만 오히려 좋아!!!!!! 매일 시위현장에 나가기 어려운 상황에 우리가 일상속에서 연대할 수 있는 방법은 무엇일까 고민하며 개발했습니다.

미니프로젝트를 이렇게 빨리 만들게 된 건 촛불게임잼이라는 행사를 알게 된 것이 시작이었습니다. 제가 게임 개발자는 아니지만 웹으로 개발할 수 있는 간단한 게임 형태의 웹앱이면 촛불게임잼에 참가하기에 충분하지 않을까 싶어 빠르게 떠오르는대로 기획에 들어갔고, 기본 구조 마크업과 기능을 우선 개발 한 뒤 이를 바탕으로 디자이너 동료에게 연대 요청을 해 가독성과 기획을 더 보강할 수 있는 디자인을 같이 실시간으로 소통하며 작업을 발전시켰습니다.

어렸을 때 한번쯤 해봤을 비내리는 타자 연습에 착안한 플레이 방식을 택했습니다. 그리고 원색적인 비난과 조롱보다는 기본적인 헌법도 지키지 않는 국회위원, 대통령의 이름을 모두가 기억할 수 있도록 하자는 큰 취지를 해치지 않는 UX/UI를 구상해 나갔습니다. 게임의 재미를 살리기 위해 60초 카운트 다운, 헌법 조항과 게임 완료 후 점수와 문구를 띄워주는 모달 UI를 추가하며 살을 붙여나갔습니다.

동료들이 3일이라는 짧은 기간 동안 각자 퇴근 후 시간을 쪼개어 함께 해주어 멋진 결과물로 완성할 수 있었다고 생각합니다. 함께 해준 동료들에게 감사합니다!

105+1 탄핵 타자 연습
https://impeachment-for-democracy.vercel.app

탄핵타자연습4.png|400
탄핵타자연습2.png|400

제1회 촛불게임잼 참여 보드 (링크에서 다른 참여자분들의 게임도 볼 수 있습니다)
https://itch.io/jam/candle-1/entries
Screenshot 2024-12-15 at 10.48.10 PM.png|400
Screenshot 2024-12-15 at 10.45.14 PM.png|400

개발하면서 만난 문제 해결 과정도 기록해보겠습니다.

input에 텍스트를 입력하고 엔터 키를 누르면 입력한 이름을 타이틀 컴포넌트에 띄워주고, 입력한 이름이 아래로 떨어지는 이름과 매칭되면 화면에서 제거합니다.


const [inputText, setInputText] = useState<string>("");
const [matchedText, setMatchedText] = useState<string>("");

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
	setInputText(event.currentTarget.value);
};

  
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
	if (event.key === "Enter") {
		setMatchedText(event.currentTarget.value);
	}
};

<input
	autoFocus
	type="text"
	value={inputText}
	onChange={handleInputChange}
	onKeyDown={handleKeyDown}
	placeholder="텍스트를 입력 후 엔터 키를 눌러주세요."
/>

그런데 이렇게 코드를 작성하면 엔터를 치는 순간 matchedText에 최신의 input value가 아니라 가장 마지막 글자만 셋되는 문제가 생겼습니다.

원인은 아래와 같습니다.

keydown 이벤트 핸들러에서 event.currentTarget.value가 마지막 글자만 가져오는 이유는 keydown 이벤트가 발생할 때, input의 값이 아직 업데이트되지 않았기 때문입니다. keydown 이벤트는 키가 눌렸을 때 발생하며, 이 시점에서는 input의 값이 변경되기 전입니다.

예를 들어, input 필드에 "탄핵타자연습"을 입력하고 Enter 키를 누르면, keydown 이벤트 핸들러가 호출됩니다. 이 시점에서는 input의 값이 아직 "탄핵타자연습"로 업데이트되지 않았기 때문에 event.currentTarget.value는 "탄핵타자연습"이 아닌 "탄핵타자연습"의 마지막 글자 "습"만 가져오게 됩니다.

onChange 이벤트와 keydown 이벤트의 발생 순서

  1. keydown 이벤트: 키가 눌렸을 때 발생합니다. 이 시점에서는 input의 값이 아직 변경되지 않았습니다.
  2. input 값 업데이트: 키가 눌린 후에 input의 값이 변경됩니다.
  3. onChange 이벤트input의 값이 변경된 후에 발생합니다.

이를 해결하기 위해서는 아래처럼 onChange 이벤트 핸들러에서 상태를 업데이트하고, keydown 이벤트 핸들러에서 상태를 사용하는 것이 좋습니다. onChange 이벤트는 input의 값이 실제로 변경된 후에 발생하므로, 전체 값을 정확하게 가져올 수 있습니다.


const [inputText, setInputText] = useState<string>("");
const [matchedText, setMatchedText] = useState<string>("");

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
	setInputText(event.currentTarget.value);
};

  
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
	if (event.key === "Enter") {
		setMatchedText(inputText);
	}
};

<input
	autoFocus
	type="text"
	value={inputText}
	onChange={handleInputChange}
	onKeyDown={handleKeyDown}
	placeholder="텍스트를 입력 후 엔터 키를 눌러주세요."
/>