๋ผ๋ถ๋ถ๋ก ์์๋ณด๋ ๋์ ์ฑ๊ฒฉ ์ ํ ๐
https://github.com/MAS-MIRIM/Popick_Frontend
- ๋ด๋น : ๊ธฐํ, FE ๊ฐ๋ฐ (React Native)
- 25.07.26 ~ 25.07.27, U/THON 25
Popick์ ์ธ๊ธฐ ์ํธํ ์ด '๋ผ๋ถ๋ถ' ์บ๋ฆญํฐ๋ฅผ ํ์ฉํ ํผ์ค๋๋ฆฌํฐ ํ ์คํธ ์๋น์ค์ ๋๋ค. ์ฌ์ฉ์๋ค์ด 10๊ฐ์ ๊ฐ๋จํ ์ง๋ฌธ์ ๋ตํ๋ฉด, ์์ ๊ณผ ๊ฐ์ฅ ์ ๋ง๋ ๋ผ๋ถ๋ถ ์บ๋ฆญํฐ๋ฅผ ๋งค์นญํด์ฃผ๋ ๋ชจ๋ฐ์ผ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ค.
๋ณธ ํ๋ก์ ํธ๋ U/THON 25 ํด์ปคํค์์ 2์ผ๊ฐ ์งํ๋์์ผ๋ฉฐ, MZ์ธ๋์ ํธ๋ ๋์ธ ์ํธํ ์ด ๋ฌธํ์ ์ฑ๊ฒฉ ํ ์คํธ๋ฅผ ๊ฒฐํฉํ์ฌ ์ฌ๋ฏธ์๊ณ ์ง๊ด์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค. React Native๋ฅผ ํ์ฉํ์ฌ iOS์ Android ํ๋ซํผ์ ๋์์ ์ง์ํ๋ ํฌ๋ก์ค ํ๋ซํผ ์ฑ์ผ๋ก ๊ฐ๋ฐ๋์์ต๋๋ค.
ํนํ ์ฑ๊ฒฉ ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก ๋ง์ถคํ ์ ํ๋ธ ์ผ์ธ ๋ฅผ ์ถ์ฒํ๊ณ , ๋ค์ํ ๋ผ๋ถ๋ถ ์บ๋ฆญํฐ๋ค์ ์์งํ ์ ์๋ ๋๊ฐ ๊ธฐ๋ฅ์ ํตํด ์ง์์ ์ธ ์ฌ์ฉ์ ์ธ๊ฒ์ด์ง๋จผํธ๋ฅผ ์ ๋ํฉ๋๋ค.
- ์ด๋ฉ์ผ ๊ธฐ๋ฐ ํ์๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ
- JWT ํ ํฐ ๊ธฐ๋ฐ ์ธ์ฆ ์์คํ
- ์๋ ๋ก๊ทธ์ธ ๋ฐ ์ธ์ ์ ์ง
- 10๊ฐ์ ์ด์ง ์ ํํ ์ง๋ฌธ์ผ๋ก ๊ตฌ์ฑ
- ๊ฐ ๋ต๋ณ์ ๋ฐ๋ฅธ ๋ผ๋ถ๋ถ ์บ๋ฆญํฐ ํฌ์ธํธ ๊ณ์ฐ
- ์ค์๊ฐ ์งํ๋ฅ ํ์ ๋ฐ ์ ๋๋ฉ์ด์ ํจ๊ณผ
- 8๊ฐ์ง ๋ผ๋ถ๋ถ ์บ๋ฆญํฐ ์ค ์ต์ ๋งค์นญ
- ์บ๋ฆญํฐ๋ณ ์์ธ ์ฑ๊ฒฉ ์ค๋ช ์ ๊ณต
- ๊ฒฐ๊ณผ ์ด๋ฏธ์ง ์ ์ฅ ๋ฐ SNS ๊ณต์ ๊ธฐ๋ฅ
- ์ธ๊ธฐ ๋ผ๋ถ๋ถ ์บ๋ฆญํฐ ํธ๋ ๋ฉ ํ์
- ์บ๋ฆญํฐ๋ณ ์ข์์ ๊ธฐ๋ฅ
- ๋ฐฐ๋ ์ฌ๋ผ์ด๋ ๋ฐ ๊ฒ์ ๊ธฐ๋ฅ
- ์ฑ๊ฒฉ ํ ์คํธ ๊ฒฐ๊ณผ ๊ธฐ๋ฐ ๋ง์ถคํ ์ผ์ธ ์ถ์ฒ
- WebView๋ฅผ ํตํ ์ธ์ฑ ๋์์ ์ฌ์
- ๋ฌดํ ์คํฌ๋กค ๋ฐ ํ์ด์ง๋ค์ด์
- ์์งํ ๋ผ๋ถ๋ถ ์บ๋ฆญํฐ ๊ฐค๋ฌ๋ฆฌ
- ์บ๋ฆญํฐ๋ณ ์์ธ ์ ๋ณด ๋ชจ๋ฌ
- ์์ง ์งํ๋ฅ ํ์
- ํ๋กํ ์ ๋ณด ๊ด๋ฆฌ
- ์ฑ๊ฒฉ ํ ์คํธ ์ฌ์งํ
- ์ข์์ํ ์บ๋ฆญํฐ ๋ชฉ๋ก
- ๋ก๊ทธ์์ ๊ธฐ๋ฅ
- ์์ด๋์ด ๊ตฌ์ฒดํ : ํ์์ ์ ์ํ ์์ด๋์ด๋ฅผ ์ ๋ฆฌํ๊ณ , ๊ธฐ๋ฅ์ผ๋ก ์ธ๋ถํํ๋ ๊ณผ์ ์ ์ฐธ์ฌํ์ต๋๋ค.
- ์ ์ฒด FE ๊ฐ๋ฐ : React Native๋ฅผ ํ์ฉํ ํฌ๋ก์ค ํ๋ซํผ ๋ชจ๋ฐ์ผ ์ฑ ์ ์ฒด ๊ฐ๋ฐ
- ์ปดํฌ๋ํธ ์ํคํ ์ฒ ์ค๊ณ ๋ฐ ๊ตฌํ
- React Navigation ๊ธฐ๋ฐ ํ๋ฉด ์ ํ ๋ก์ง
- AsyncStorage๋ฅผ ํ์ฉํ ๋ก์ปฌ ๋ฐ์ดํฐ ์์์ฑ ๊ด๋ฆฌ
- API ์๋น์ค ๋ ์ด์ด ๊ตฌํ ๋ฐ ํ์ ์ ์
- styled-components๋ฅผ ํ์ฉํ ์คํ์ผ๋ง
- ์ฑ๊ฒฉ ํ ์คํธ ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ ๋ฐ ๊ฒฐ๊ณผ ๊ณ์ฐ ๋ก์ง
- WebView ๊ธฐ๋ฐ ์ ํ๋ธ ์ผ์ธ ํตํฉ
๋ฌธ์ ์ํฉ
- iOS ๋น๋ ์
pod install๊ณผ์ ์์ ์ง์์ ์ธ ์คํจ - Ruby ๋ฒ์ ๋ถ์ผ์น๋ก ์ธํ CocoaPods ์คํ ์ค๋ฅ
- React Native 0.70.10๊ณผ ํธํ๋๋ Pod ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฒ์ ์ถฉ๋
ํด๊ฒฐ ๊ณผ์
- rbenv๋ฅผ ํตํด ํ๋ก์ ํธ๋ณ Ruby ๋ฒ์ ๊ด๋ฆฌ (3.2.2๋ก ๊ณ ์ )
pod repo update๋ฐpod install --repo-update๋ช ๋ น์ผ๋ก ์ ์ฅ์ ๋๊ธฐํ- Podfile.lock ์ญ์ ํ ํด๋ฆฐ ๋น๋๋ก ์์กด์ฑ ์ฌ๊ตฌ์ฑ
fix-android-manifests.js์คํฌ๋ฆฝํธ ์์ฑ์ผ๋ก Android ๋น๋ ์ด์ ๋์ ํด๊ฒฐ
๊ฒฐ๊ณผ
- ์์ ์ ์ธ iOS/Android ๋์ ๋น๋ ํ๊ฒฝ ๊ตฌ์ถ
- ํ์๋ค๋ ๋์ผํ ํ๊ฒฝ์์ ๋น๋ ๊ฐ๋ฅํ๋๋ก ๋ฌธ์ํ
๋ฌธ์ ์ํฉ
- ๋ฐฑ์๋ ํ๊ณผ ๋ณ๋๋ก ๊ฐ๋ฐ ์งํ์ผ๋ก ์ธํ API ์คํ ๋ถ์ผ์น
- ๋ฐํ์์์ ์์์น ๋ชปํ undefined ์๋ฌ ๋ฐ์
- ์ฑ๊ฒฉ ํ ์คํธ ๊ฒฐ๊ณผ ๊ณ์ฐ ์ ํ์ ์๋ฌ๋ก ์ฑ ํฌ๋์
ํด๊ฒฐ ๊ณผ์
utils/api.ts์ ํ์ ๊ฐ๋ ํจ์ ๊ตฌํ- Zod ์คํค๋ง ๊ฒ์ฆ ๋์ ๊ฒํ ํ ์๊ฐ ์ ์ฝ์ผ๋ก ์๋ ํ์ ์ฒดํฌ ๊ตฌํ
- Mock ๋ฐ์ดํฐ์ ์ค์ API ์๋ต ๊ฐ ์ ํ ๊ฐ๋ฅํ ์ถ์ํ ๋ ์ด์ด ๊ตฌ์ถ
- ์ต์ ๋ ์ฒด์ด๋๊ณผ nullish coalescing์ผ๋ก ๋ฐฉ์ด์ ์ฝ๋ฉ
๊ฒฐ๊ณผ
- API ์๋ต ๋ถ์ผ์น์๋ ์ฑ์ด ํฌ๋์ํ์ง ์๊ณ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌ
- ๊ฐ๋ฐ ์ค Mock ๋ฐ์ดํฐ๋ก ๋ ๋ฆฝ์ ์ธ ํ๋ก ํธ์๋ ๊ฐ๋ฐ ๊ฐ๋ฅ
๋ฌธ์ ์ํฉ
- ๋ง์ง๋ง ์ง๋ฌธ์์ "๋ค์" ๋ฒํผ ์ฐ์ ํด๋ฆญ ์ ๊ฒฐ๊ณผ๊ฐ ์ค๋ณต ์ ์ถ
- ๋น๋๊ธฐ ์ํ ์ ๋ฐ์ดํธ๋ก ์ธํ race condition ๋ฐ์
- 10๊ฐ ์ง๋ฌธ ์๋ฃ ํ 11๊ฐ, 12๊ฐ์ ๋ต๋ณ์ด ์๋ฒ๋ก ์ ์ก๋๋ ๋ฒ๊ทธ
ํด๊ฒฐ ๊ณผ์
useRef๋ฅผ ํ์ฉํ ์ฆ๊ฐ์ ์ธ ์ฒ๋ฆฌ ์ํ ํ๋๊ทธ ๊ตฌํ- ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ์ ์ค๋ณต ํด๋ฆญ ๋ฐฉ์ง ๋ก์ง ์ถ๊ฐ
- ๋ต๋ณ ๋ฐฐ์ด ๊ธธ์ด ๊ฒ์ฆ์ผ๋ก ์ถ๊ฐ ๋ฐฉ์ด ๋ก์ง ๊ตฌํ
- ๋๋ฐ์ด์ฑ๊ณผ ์ฐ๋กํ๋ง ๊ธฐ๋ฒ ์ ์ฉ ๊ฒํ
์ฝ๋ ์์
const processingRef = useRef(false);
const handleNext = async () => {
if (processingRef.current || answers.length >= 10) return;
processingRef.current = true;
// ... ์ฒ๋ฆฌ ๋ก์ง
processingRef.current = false;
};๊ฒฐ๊ณผ
- ์ค๋ณต ์ ์ถ ๋ฒ๊ทธ ์์ ํด๊ฒฐ
- ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ ๋ฐ ์๋ฒ ๋ถํ ๊ฐ์
๋ฌธ์ ์ํฉ
- 2์ผ๊ฐ์ ํด์ปคํค์์ ๊ธฐํ๋ถํฐ ๋ฐฐํฌ๊น์ง ์๋ฃ ํ์
- 8๋ช ์ ํ์ ๊ฐ ํจ์จ์ ์ธ ํ์ ์ฒด๊ณ ๊ตฌ์ถ ํ์
- ์์ฑ๋ ์๋ ์ ํ๊ณผ ์๊ฐ ์ ์ฝ ๊ฐ์ ๊ท ํ
ํด๊ฒฐ ๊ณผ์
- ํต์ฌ ๊ธฐ๋ฅ ์ฐ์ ์์ ์ ์ (์ฑ๊ฒฉ ํ ์คํธ > ๊ฒฐ๊ณผ ํ์ > ๋๊ฐ > ์ผ์ธ )
- ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ์ฑ ๊ทน๋ํ๋ก ๊ฐ๋ฐ ์๋ ํฅ์
- styled-components ํ ๋ง ํ์ฉ์ผ๋ก ์ผ๊ด๋ ๋์์ธ ์์คํ ๊ตฌ์ถ
- Git Flow ๊ฐ์ํ ๋ฐ ์ค์๊ฐ ์ฝ๋ ๋ฆฌ๋ทฐ ์งํ
๊ฒฐ๊ณผ
- ๊ณํํ ๋ชจ๋ ํต์ฌ ๊ธฐ๋ฅ ๊ตฌํ ์๋ฃ
- ์์ ์ ์ธ MVP ๋ฒ์ ํด์ปคํค ์์ฐ ์ฑ๊ณต