| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- 유니티 안드로이드 빌드
- 깃허브뱃지
- 코드트리조별과제
- javascript
- 데이터베이스
- vscode
- 박스 모델
- 파이썬
- 주석 단축키
- html
- 코딩테스트
- 학습회고
- 유니티
- CSS
- 코드트리
- 오블완
- #UMC #UMC10기 #UMC 블로그챌린지 #IT동아리
- 웹 개발
- 유니티 에디터
- 티스토리챌린지
- route53
- react
- 기술심화
- 프론트엔드
- 유니티 모듈
- SQL
- HeidiSQL
- #AwsCloudClubs
- GitHub
- 깃허브
- Today
- Total
Hello It's good to be back ^_^
[UMC 블로그챌린지] Web 파트 2주차 useState와 useReducer에 대해 알아보기 본문
들어가기 전에 앞서, 솔직히 나는 훅이 뭔지, useState가 뭔지도 잘 모르기 때문에 우선 개념 정리가 필요했다
개념정리
자바스크립트에서 화살표 함수의 형태
//기본 형태
const 함수명 = (매개변수) => { 함수내용 }
//사용 예시
const Button = ({ onClick, text }: ButtonProps) => {
return <button onClick={onClick}>{text}</button>;
};
//해석
// Button이라는 함수는 ButtonProps 타입의 객체를 매개변수로 받으며,
// 이를 구조 분해해 만든 버튼 요소를 리턴한다
JSX
: JavaScript + HTML/XML 로 둘의 문법이 혼용해서 사용한다. 참고 영상
https://www.youtube.com/watch?v=hyNQpRdS0rY&list=PLo3AHtncM26y0qX58gjc_QrkYlBCzQ2R_&index=10
자바스크립트에서의 객체
: { }를 이용해서 나타내고 멤버로는 key : value형의 변수와 함수이다
컴포넌트란?
: props라는 데이터를 매개변수로 입력받아 UI(자바스크립트 객체)를 출력하는 ‘함수’
props란?
: 컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체, 부모 컴포넌트가 자식 컴포넌트에게 전달해주는 자바스크립트 객체
state란?
: 리액트 엔진이 관리하는 컴포넌트 전용 메모리 공간에 저장된 자바스크립트 값
: 컴포넌트가 기억하는 값, 컴포넌트 내부에서 관리하는 변할 수 있는 값
- 다른 일반프로그래밍 언어에서 변수와 같은 역할을 한다고 뭉뜽그려서 말할 수 있다. 리액트는 변수가 아니라 '상태'를 기준으로 화면을 바꾸기 때문에 상태를 이용하는 것이 기본이다. 훅은 이러한 상태의 값을 바꿀 수 있게하는 자바스크립트 함수이다
구조분해할당
: 객체나 배열에서 필요한 값만 추출하여 지역 변수로 즉시 선언하는 문법
- 리액트의 훅은 배열을 리턴한다. 우리는 훅이 리턴한 배열의 요소들을 이용해야하는데 매번 배열[인덱스]로 접근하면 불편할 것이다. 그래서 처음 훅이 리턴할 때부터 각각의 배열의 요소들을 따로 분해해서 변수로 받아 사용한다. 이것은 구조를 분해해서 할당한다는 의미로 구조분해할당이라고 한다.
사용예시
객체 분해
//구조분해할당 사용 전
function Profile(props) {
// 매번 props.xxx 라고 써야 함
return <h1>{props.name}님, 나이는 {props.age}살이군요.</h1>;
}
//구조분해할당 사용 후
function Profile({ name, age }) {
// props 객체에서 name과 age라는 키(key)를 가진 값만 쏙 뽑아서 변수로 만듦
return <h1>{name}님, 나이는 {age}살이군요.</h1>;
}
배열 분해
const [count, setCount] = useState(0);
1. useState()은 [0, 함수]라는 원소를 가진 배열을 리턴한다.
2. 각각의 배열의 요소를 count라는 변수와 setCount()라는 함수에 할당한다
useState()
: 변하는 데이터를 기억하고, 그 데이터에 맞춰 화면을 자동으로 바꿔주는 자바스크립트 함수
//사용 형식
const [state, setState] = useState(initialValue);
state: 컴포넌트에서 사용할 데이터
setState: state 값을 변경할 때 사용하는 함수
initialValue:state의 초기값
//사용 예시
import { useState } from 'react';
function Counter() {
// 1. 'count'라는 상태를 0으로 시작하겠다고 리액트 금고에 예약함
const [count, setCount] = useState(0);
return (
<div>
<p>현재 값: {count}</p>
{/* 2. 버튼 클릭 시 setCount 함수로 값을 1 증가시킴 */}
{/* 3. 리액트가 알람을 듣고 Counter 함수를 다시 실행함 */}
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
useReducer()
: useState와 같은 상태를 관리하는 훅
: 관리해야할 상태가 많아질 때 구조적으로 사용하기 위해 이용한다
//사용 형식
const [state, dispatch] = useReducer(reducer, initialState);
useReducer의 4가지 핵심 구성 요소
- 상태 (State): 관리할 데이터의 현재 값 (은행 잔고).
- 액션 (Action): 무엇을 할지 적힌 주문서 (입금, 출금, 송금 등). 보통 { type: 'DEPOSIT', payload: 1000 } 같은 객체 형태입니다.
- 리듀서 (Reducer): 주문서를 보고 실제로 돈을 계산하는 함수. (상태를 변경하는 로직이 담긴 본체)
- 디스패치 (Dispatch): 주문서를 은행 창구(Reducer)에 전달하는 행위.
//사용 예시
// 1. 리듀서 함수: (현재 상태, 주문서)를 받아서 '새로운 상태'를 반환함
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 }; // 새 객체 반환
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
// 2. useReducer(리듀서함수, 초기값) 호출
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
<h1>{state.count}</h1>
{/* 3. dispatch를 통해 '주문서(action)'를 보냄 */}
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
</>
);
}
복잡한 구조를 컴팩트하기 만들기 위해 사용한다는 것은 알았다.
정리된 블로그를 보면서 내가 1학년 때 작업한 게임 프로젝트가 생각났는데 당시 작성했던 코드를 하나 가져오자면
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;
public class CafeGame : MonoBehaviour
{
public GameObject[] FruitsPrefabs;
public GameObject[] ReceiptPrefabs;
public List<GameObject> Order1 = new List<GameObject>();
public List<GameObject> Order2 = new List<GameObject>();
public List<GameObject> Order3 = new List<GameObject>();
public List<GameObject> Order4 = new List<GameObject>();
public List<GameObject> Order5 = new List<GameObject>();
public List<GameObject> Order1Name = new List<GameObject>();
public List<GameObject> Order2Name = new List<GameObject>();
public List<GameObject> Order3Name = new List<GameObject>();
public List<GameObject> Order4Name = new List<GameObject>();
public List<GameObject> Order5Name = new List<GameObject>();
public VerticalLayoutGroup Order1NameVertical;
public VerticalLayoutGroup Order2NameVertical;
public VerticalLayoutGroup Order3NameVertical;
public VerticalLayoutGroup Order4NameVertical;
public VerticalLayoutGroup Order5NameVertical;
public List<GameObject> TotalClickedFruits = new List<GameObject>();
public List<GameObject> TotalFruitImage = new List<GameObject>();
public List<GameObject> TotalFruitName = new List<GameObject>();
public VerticalLayoutGroup ClickFruitsVertical;
public VerticalLayoutGroup ClickNameVertical;
private GameObject ReceiptObj1;
private GameObject ReceiptObj2;
private GameObject ReceiptObj3;
private GameObject ReceiptObj4;
private GameObject ReceiptObj5;
[SerializeField] private GameObject BlenderBtn;
[SerializeField] private Sprite[] BlenderSprite;
public int money = 0;
private float yPosBox =2;
private int fruitsCount;
public int clickCount = 0;
public TMP_FontAsset customFont;
[SerializeField]
private TextMeshProUGUI moneyNumTextInStartPanel;
public AudioClip successSound; // 성공 사운드 클립
private AudioSource audioSource;
private int fortuneId;
void Start()
{
money = 0;
clickCount = 0;
audioSource = GetComponent<AudioSource>();
fortuneId = DayFortune.GetTodayFortuneId();
Debug.Log("운세번호: " + fortuneId);
}
void Update()
{
if (TotalClickedFruits.Count < 5)
{
if (Input.GetMouseButtonDown(0)) //클릭한 과일 인식
{
Vector2 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero, Mathf.Infinity);
if (hit.collider != null && hit.collider.gameObject.name != "GarbageBtn")
{
GameObject clickedObject = hit.collider.gameObject;
TotalClickedFruits.Add(clickedObject);
clickCount++;
//클릭한 과일 이미지 생성
Sprite fruitSprite = clickedObject.GetComponent<SpriteRenderer>().sprite; //클릭한 과일의 스프라이트를 가져옴
GameObject fruitImageObject = new GameObject("FruitImage", typeof(RectTransform)); //RectTransform 컴포넌트를 가진 오브젝트 생성
fruitImageObject.AddComponent<Image>().sprite = fruitSprite; //생성된 오브젝트에 이미지 컴포넌트를 추가하고 클릭한 과일의 이미지를 넣음
RectTransform RectTransform1 = fruitImageObject.GetComponent<RectTransform>();
RectTransform1.SetParent(ClickFruitsVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
TotalFruitImage.Add(fruitImageObject); //생성된 오브젝트를 리스트에 추가
// 클릭한 과일 이름 생성
string FruitName = clickedObject.name;
GameObject FruitNameObj = new GameObject("FruitNameText");
FruitNameObj.AddComponent<TextMeshProUGUI>().text = FruitName;
TextMeshProUGUI textMeshPro = FruitNameObj.GetComponent<TextMeshProUGUI>();
textMeshPro.font = customFont;
textMeshPro.color = Color.black;
textMeshPro.fontSize = 63;
RectTransform rectTransform2 = FruitNameObj.GetComponent<RectTransform>();
rectTransform2.SetParent(ClickNameVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
rectTransform2.sizeDelta = new Vector2(260f, rectTransform2.sizeDelta.y);
TotalFruitName.Add(FruitNameObj);
}
}
//실시간 번 돈 나타내기
moneyNumTextInStartPanel.SetText(money.ToString()+"만원");
//과일을 클릭한 횟수에 따라 블랜더의 이미지 변경
Image imageComponent = BlenderBtn.GetComponent<Image>();
switch(clickCount)
{
case 0:
imageComponent.sprite = BlenderSprite[0];
imageComponent.SetNativeSize();
break;
case 1:
imageComponent.sprite = BlenderSprite[1];
imageComponent.SetNativeSize();
break;
case 2:
imageComponent.sprite = BlenderSprite[2];
imageComponent.SetNativeSize();
break;
case 3:
imageComponent.sprite = BlenderSprite[3];
imageComponent.SetNativeSize();
break;
case 4:
imageComponent.sprite = BlenderSprite[4];
imageComponent.SetNativeSize();
break;
case 5:
imageComponent.sprite = BlenderSprite[5];
imageComponent.SetNativeSize();
break;
}
// if(TotalClickedFruits.Count == 0)
// {
// imageComponent.sprite = BlenderSprite[0];
// imageComponent.SetNativeSize();
// }
//과일 이름 표시
// string allClickedObjectNames = "";
// foreach (var FruitsObject in TotalClickedFruits)
// {
// allClickedObjectNames += FruitsObject.name + "\n";
// }
// clickedObjectNameText.SetText(allClickedObjectNames);
}
}
public void SpawnFruits_1()
{
if (fortuneId == 7) //알바 하드모드 운세일 경우
{
float p = Random.value;
Debug.Log("1번 과일개수확률: " + p);
if(p < 0.3f) //30%확률로 과일의 개수가 3개 나올 수도 있음
fruitsCount = 3;
else
fruitsCount = Random.Range(4, 6); //70%확률로 과일의 개수 4, 5개
}
else
fruitsCount = Random.Range(3, 6); //한 주문에 나오는 과일의 개수 3~5개 사이
for (int i = 0; i < fruitsCount; i++)
{
//과일 생성
float yPos = 2.8f - 0.6f*i;
Vector3 spawnPosition = new Vector3(-5.6f, yPos, 0);
int randNum = Random.Range(0, FruitsPrefabs.Length);
GameObject RandomFruit = FruitsPrefabs[randNum];
GameObject FruitsObj = Instantiate(RandomFruit, spawnPosition, Quaternion.identity);
Order1.Add(FruitsObj);
//과일 이름 생성
string fruitName = FruitsObj.name.Replace("(Clone)", ""); //생성된 과일 오브젝트의 이름에서 클론을 떼고 저장
GameObject FruitNameObj = new GameObject("FruitNameText");
FruitNameObj.AddComponent<TextMeshProUGUI>().text = fruitName;
TextMeshProUGUI textMeshPro = FruitNameObj.GetComponent<TextMeshProUGUI>();
textMeshPro.font = customFont;
textMeshPro.color = Color.black;
textMeshPro.fontSize = 15;
//배치 버티컬 구조
RectTransform rectTransform = FruitNameObj.GetComponent<RectTransform>();
rectTransform.SetParent(Order1NameVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
Order1Name.Add(FruitNameObj);
}
//주문 영수증 오브젝트 생성
Vector3 spawnPositionBox = new Vector3(-5f, yPosBox, 0);
GameObject ReceiptObj = ReceiptPrefabs[0];
ReceiptObj1 = Instantiate(ReceiptObj, spawnPositionBox, Quaternion.identity);
}
public void SpawnFruits_2()
{
if (fortuneId == 7) //알바 하드모드 운세일 경우
{
float p = Random.value;
Debug.Log("2번 과일개수확률: " + p);
if(p < 0.3f) //30%확률로 과일의 개수가 3개 나올 수도 있음
fruitsCount = 3;
else
fruitsCount = Random.Range(4, 6); //70%확률로 과일의 개수 4, 5개
}
else //하드모드 운세가 아닐경우
fruitsCount = Random.Range(3, 6); //한 주문에 나오는 과일의 개수 3~5개 사이
for (int i = 0; i < fruitsCount; i++)
{
float yPos = 2.8f - 0.6f*i;
Vector3 spawnPosition = new Vector3(-3.1f, yPos, 0);
int randNum = Random.Range(0, FruitsPrefabs.Length);
GameObject RandomFruit = FruitsPrefabs[randNum];
GameObject FruitsObj = Instantiate(RandomFruit, spawnPosition, Quaternion.identity);
Order2.Add(FruitsObj);
GameObject FruitNameObj = new GameObject("FruitNameText");
string fruitName = FruitsObj.name.Replace("(Clone)", "");
FruitNameObj.AddComponent<TextMeshProUGUI>().text = fruitName;
TextMeshProUGUI textMeshPro = FruitNameObj.GetComponent<TextMeshProUGUI>();
textMeshPro.font = customFont;
textMeshPro.color = Color.black;
textMeshPro.fontSize = 15;
RectTransform rectTransform = FruitNameObj.GetComponent<RectTransform>();
rectTransform.SetParent(Order2NameVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
Order2Name.Add(FruitNameObj);
}
Vector3 spawnPositionBox = new Vector3(-2.5f, yPosBox, 0);
GameObject ReceiptObj = ReceiptPrefabs[0];
ReceiptObj2 = Instantiate(ReceiptObj, spawnPositionBox, Quaternion.identity);
}
public void SpawnFruits_3()
{
if (fortuneId == 7) //알바 하드모드 운세일 경우
{
float p = Random.value;
Debug.Log("3번 과일개수확률: " + p);
if(p < 0.3f) //30%확률로 과일의 개수가 3개 나올 수도 있음
fruitsCount = 3;
else
fruitsCount = Random.Range(4, 6); //70%확률로 과일의 개수 4, 5개
}
else
fruitsCount = Random.Range(3, 6); //한 주문에 나오는 과일의 개수 3~5개 사이
for (int i = 0; i < fruitsCount; i++)
{
float yPos = 2.8f - 0.6f*i;
Vector3 spawnPosition = new Vector3(-0.6f, yPos, 0);
int randNum = Random.Range(0, FruitsPrefabs.Length);
GameObject RandomFruit = FruitsPrefabs[randNum];
GameObject FruitsObj = Instantiate(RandomFruit, spawnPosition, Quaternion.identity);
Order3.Add(FruitsObj);
GameObject FruitNameObj = new GameObject("FruitNameText");
string fruitName = FruitsObj.name.Replace("(Clone)", "");
FruitNameObj.AddComponent<TextMeshProUGUI>().text = fruitName;
TextMeshProUGUI textMeshPro = FruitNameObj.GetComponent<TextMeshProUGUI>();
textMeshPro.font = customFont;
textMeshPro.color = Color.black;
textMeshPro.fontSize = 15;
RectTransform rectTransform = FruitNameObj.GetComponent<RectTransform>();
rectTransform.SetParent(Order3NameVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
Order3Name.Add(FruitNameObj);
}
Vector3 spawnPositionBox = new Vector3(0f, yPosBox, 0);
GameObject ReceiptObj = ReceiptPrefabs[0];
ReceiptObj3 = Instantiate(ReceiptObj, spawnPositionBox, Quaternion.identity);
}
public void SpawnFruits_4()
{
if (fortuneId == 7) //알바 하드모드 운세일 경우
{
float p = Random.value;
Debug.Log("4번 과일개수확률: " + p);
if(p < 0.3f) //30%확률로 과일의 개수가 3개 나올 수도 있음
fruitsCount = 3;
else
fruitsCount = Random.Range(4, 6); //70%확률로 과일의 개수 4, 5개
}
else
fruitsCount = Random.Range(3, 6); //한 주문에 나오는 과일의 개수 3~5개 사이
for (int i = 0; i < fruitsCount; i++)
{
float yPos = 2.8f - 0.6f*i;
Vector3 spawnPosition = new Vector3(1.9f, yPos, 0);
int randNum = Random.Range(0, FruitsPrefabs.Length);
GameObject RandomFruit = FruitsPrefabs[randNum];
GameObject FruitsObj = Instantiate(RandomFruit, spawnPosition, Quaternion.identity);
Order4.Add(FruitsObj);
GameObject FruitNameObj = new GameObject("FruitNameText");
string fruitName = FruitsObj.name.Replace("(Clone)", "");
FruitNameObj.AddComponent<TextMeshProUGUI>().text = fruitName;
TextMeshProUGUI textMeshPro = FruitNameObj.GetComponent<TextMeshProUGUI>();
textMeshPro.font = customFont;
textMeshPro.color = Color.black;
textMeshPro.fontSize = 15;
RectTransform rectTransform = FruitNameObj.GetComponent<RectTransform>();
rectTransform.SetParent(Order4NameVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
Order4Name.Add(FruitNameObj);
}
Vector3 spawnPositionBox = new Vector3(2.5f, yPosBox, 0);
GameObject ReceiptObj = ReceiptPrefabs[0];
ReceiptObj4 = Instantiate(ReceiptObj, spawnPositionBox, Quaternion.identity);
}
public void SpawnFruits_5()
{
if (fortuneId == 7) //알바 하드모드 운세일 경우
{
float p = Random.value;
Debug.Log("5번 과일개수확률: " + p);
if(p < 0.3f) //30%확률로 과일의 개수가 3개 나올 수도 있음
fruitsCount = 3;
else
fruitsCount = Random.Range(4, 6); //70%확률로 과일의 개수 4, 5개
}
else
fruitsCount = Random.Range(3, 6); //한 주문에 나오는 과일의 개수 3~5개 사이
for (int i = 0; i < fruitsCount; i++)
{
float yPos = 2.8f - 0.6f*i;
Vector3 spawnPosition = new Vector3(4.4f, yPos, 0);
int randNum = Random.Range(0, FruitsPrefabs.Length);
GameObject RandomFruit = FruitsPrefabs[randNum];
GameObject FruitsObj = Instantiate(RandomFruit, spawnPosition, Quaternion.identity);
Order5.Add(FruitsObj);
GameObject FruitNameObj = new GameObject("FruitNameText");
string fruitName = FruitsObj.name.Replace("(Clone)", "");
FruitNameObj.AddComponent<TextMeshProUGUI>().text = fruitName;
TextMeshProUGUI textMeshPro = FruitNameObj.GetComponent<TextMeshProUGUI>();
textMeshPro.font = customFont;
textMeshPro.color = Color.black;
textMeshPro.fontSize = 15;
RectTransform rectTransform = FruitNameObj.GetComponent<RectTransform>();
rectTransform.SetParent(Order5NameVertical.transform, false); //버티컬 레이아웃의 자식요소로 들어가게 함
Order5Name.Add(FruitNameObj);
}
Vector3 spawnPositionBox = new Vector3(5f, yPosBox, 0);
GameObject ReceiptObj = ReceiptPrefabs[0];
ReceiptObj5 = Instantiate(ReceiptObj, spawnPositionBox, Quaternion.identity);
}
public void ReceiptManager()
{
if (Order1.Count == 0)
Destroy(ReceiptObj1);
if (Order2.Count == 0)
Destroy(ReceiptObj2);
if (Order3.Count == 0)
Destroy(ReceiptObj3);
if (Order4.Count == 0)
Destroy(ReceiptObj4);
if (Order5.Count == 0)
Destroy(ReceiptObj5);
}
public void DestroyOrder(List<GameObject> Order, List<GameObject> OrderName)
{
for (int i = 0; i < Order.Count; i++)
{
Destroy(Order[i]);
}
Order.Clear();
for (int i = 0; i < OrderName.Count; i++)
{
Destroy(OrderName[i]);
}
OrderName.Clear();
}
public void moneyManager()
{
money += 1;
}
public void PlaySuccessSound()
{
audioSource.clip = successSound;
audioSource.Play();
}
// public void ClearClickedObj()
// {
// TotalClickedFruits.Clear();
// for (int i = 0; i < TotalFruitImageObject.Count; i++)
// {
// Destroy(TotalFruitImageObject[i]);
// }
// TotalFruitImageObject.Clear();
// }
// 2차원 리스트로 과일 주문 5개 생성하기 - 근데 어려워서 포기
// public void SpawnFruits()
// {
// for (int i = 0; i < 5; i++)
// {
// int fruitCount = Random.Range(3, 6);
// float xPos = -5.5f + 2.25f * i;
// for (int j = 0; j < fruitCount; j++)
// {
// float yPos = 3.5f - 1 * j;
// Vector3 spawnPosition = new Vector3(xPos, yPos, 0);
// int randNum = Random.Range(0, FruitsPrefabs.Length);
// GameObject RandomFruit = FruitsPrefabs[randNum];
// GameObject FruitsObj = Instantiate(RandomFruit, spawnPosition, Quaternion.identity);
// TotalOrder.Add(new List<GameObject>{FruitsObj});
// }
// float yPosBox = 1.5f + 0.5f * (5 - fruitCount);
// Vector3 spawnPositionBox = new Vector3(xPos, yPosBox, 0);
// GameObject BoxObj = BoxPrefabs[fruitCount - 3];
// Instantiate(BoxObj, spawnPositionBox, Quaternion.identity);
// }
// }
}
1학년이 겨우 C하나 배우고 작성한 코드이니 한 눈에 봐도 엄청나게 하드코딩이고 재사용이 불가능하게 써놓은 것이 보인다.
대충 세어봐도 한 스크립트 내에서 선언된 변수만 30개가 넘어가니 코드를 한눈에 파악하기 어렵고 유지보수 또한 굉장히 복잡하다.
이 코드를 직접 작성한 개발자(나)가 아니면 다른 사람이 수정하기도 어려울 것이다.
물론 처음에는 시도하는 것이 중요하지만, 개발을 할 땐 언제나 어떻게 하면 더 효율적이고 가독성이 좋은 코드를 짤지, 더 컴팩트하게 짤 수는 없을지 생각하는 논리적과정이 중요하다.
useState가 편하다고 그것만 사용한다면 위의 코드와 같은 사태가 또 다시 벌어질 것이다. 그러니 useReducer가 보기엔 어려울 지라도 써보려고 노력하는 습관을 들이려고 하자!
'Study > Web' 카테고리의 다른 글
| [UMC 블로그챌린지] Web 파트 4주차 - 기술심화 (0) | 2026.04.06 |
|---|---|
| [UMC 블로그챌린지] Web 파트 4주차- CS 전반적으로 훝어보기 (1) | 2026.04.05 |
| [ECC-프론트엔드 2팀] 17주차 스터디 (2) | 2025.01.25 |
| [ECC-프론트엔드 2팀] 17주차 스터디 (4) | 2025.01.16 |
| [ECC-프론트엔드 2팀] 16주차 스터디 (1) | 2025.01.11 |