3일간의 미니프로젝트 - 105+1 탄핵타자연습
12/14 탄핵 표결 전 완성하기 위해 3일동안 부리나케 만들어 본 미니 프로젝트 105+1 탄핵 타자 연습을 공유합니다. 국회앞 인파 속 데이터가 터지지 않아 탄핵 가결 후 올리게 됐지만 오히려 좋아!!!!!! 매일 시위현장에 나가기 어려운 상황에 우리가 일상속에서 연대할 수 있는 방법은 무엇일까 고민하며 개발했습니다.
미니프로젝트를 이렇게 빨리 만들게 된 건 촛불게임잼이라는 행사를 알게 된 것이 시작이었습니다. 제가 게임 개발자는 아니지만 웹으로 개발할 수 있는 간단한 게임 형태의 웹앱이면 촛불게임잼에 참가하기에 충분하지 않을까 싶어 빠르게 떠오르는대로 기획에 들어갔고, 기본 구조 마크업과 기능을 우선 개발 한 뒤 이를 바탕으로 디자이너 동료에게 연대 요청을 해 가독성과 기획을 더 보강할 수 있는 디자인을 같이 실시간으로 소통하며 작업을 발전시켰습니다.
어렸을 때 한번쯤 해봤을 비내리는 타자 연습에 착안한 플레이 방식을 택했습니다. 그리고 원색적인 비난과 조롱보다는 기본적인 헌법도 지키지 않는 국회위원, 대통령의 이름을 모두가 기억할 수 있도록 하자는 큰 취지를 해치지 않는 UX/UI를 구상해 나갔습니다. 게임의 재미를 살리기 위해 60초 카운트 다운, 헌법 조항과 게임 완료 후 점수와 문구를 띄워주는 모달 UI를 추가하며 살을 붙여나갔습니다.
동료들이 3일이라는 짧은 기간 동안 각자 퇴근 후 시간을 쪼개어 함께 해주어 멋진 결과물로 완성할 수 있었다고 생각합니다. 함께 해준 동료들에게 감사합니다!
- 프로젝트 소개
105+1 탄핵 타자 연습
기본적인 헌법도 지키지 않고 있는 105+1명의 국민의짐 의원들, 윤석열의 이름이 국민들의 무거운 짐처럼 떨어집니다.- 크레딧
기획, 개발 김지우
디자인 유연주
사용 서체 칠흑(박부미), Noto Sans KR
105+1 탄핵 타자 연습
https://impeachment-for-democracy.vercel.app
제1회 촛불게임잼 참여 보드 (링크에서 다른 참여자분들의 게임도 볼 수 있습니다)
https://itch.io/jam/candle-1/entries
개발하면서 만난 문제 해결 과정도 기록해보겠습니다.
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
이벤트의 발생 순서
keydown
이벤트: 키가 눌렸을 때 발생합니다. 이 시점에서는input
의 값이 아직 변경되지 않았습니다.input
값 업데이트: 키가 눌린 후에input
의 값이 변경됩니다.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="텍스트를 입력 후 엔터 키를 눌러주세요."
/>