FrontEnd Develop

상태변경함수 x prev 매개변수 세상에서 제일 쉽게 설명하기

Frisbeen 2025. 2. 14. 17:38

상태변경함수와 prev 매개변수 쓰는거 이거 뭔소리인지 모르겠는데요? 

 

상태를 변경할때 원본에 있는걸 새로 옮기지 않습니까 ? 이때 원본을 해치지 않은 불변성을 유지하는 것이 최근 트렌드

그래서 나온 방식이 prev 매개변수와 스프레드 연산자를 활용하는 것 ( 자바스크립트 )

 

prev 장점

이전 상태를 활용하고 그 이전 상태의 값을 유지하며 일부 값만 변경 할 수있음

 

 객체에서 Prev 사용법 (특정 속성만 바꿀래요)

set함수((prev) => {...prev, name :'kim'} )

const [user, setUser] = useState({ name: "Alice", age: 25 });

// ✅ 이전 상태를 유지하면서 특정 속성만 업데이트
const updateUserName = (newName) => {
  setUser((prev) => ({ ...prev, name: newName }));
};

const increaseAge = () => {
  setUser((prev) => ({ ...prev, age: prev.age + 1 }));
};

 

만약 prev 안쓰면?

 

이러고 그냥 속성만 바꿔버리면 기존값 싹 사라지고 내가 직접 설정한 name : 'kim'난 객체에 남음.

상태는 내가 설정한 거 자체로 transform되는 것이기 때문 트랜스포머임 

이거 다룰려면 prev ㄱㄱ

 

 

배열에서 prev 사용법

 

#1.

(원본 배열에다가 하나 추가할래요) -> push 쓰지마십쇼 (불변성 해침)

set함수((prev) => [...prev, newItem])

const [items, setItems] = useState(["사과", "바나나"]);

// ✅ 기존 배열을 유지하면서 새로운 값 추가
const addItem = (newItem) => {
  setItems((prev) => [...prev, newItem]); 
};

 

#2.

(원본배열에 하나 삭제할래요) -> filter 쓰십쇼 (그 Pop 쓰지마십쇼 -> 불변성 해치는 지름길임 )

prev는 다시 말하면 이전 배열이다 그쵸?

 

filter함수는 filter 함수 내부 (return값)의 조건이 합당한것만 배열을 채울게요 의 역할을 하는 함수다.

 

set함수((prev) => prev.filter(num => num !== numToRemove)) 이렇게 쓰면되는데 더러우니까 코드

const [numbers, setNumbers] = useState([1, 2, 3, 4, 5]);

// ✅ 특정 숫자 제거 (예: 3을 제거)
const removeNumber = (numToRemove) => {
  setNumbers((prev) => prev.filter(num => num !== numToRemove));
};

 

따라서 물론 filter 위 함수는 화살표 함수를 써버려서 Return 값이 없는거긴함 (참고하십쇼) 원랜

 

#3. 

배열에서 특정 요소를 업데이트 할때 ( 객체 배열일때 , 배열 내부의 객체의 속성을 바꿔야할때)

이때는 map를 쓰는데..

 

map은 순회하는거 아닌가요

그렇게만 알면 안됩니다. 순회하면서 배열을 변형하여 "새로운 배열을 반환하는 녀석입니다"

중요한점은 -> "배열의 길이가 유지된다" 외우십쇼 

따라서 순회하면서 배열의 길이는 유지하지만 값을 바꿀때는 map쓰시면 되겠네요

 

filter랑 뭐가 다른데요

filter는 배열의 길이가 달라질수 있습니다. 

 

 

아래의 예시로 특정 id를 가진 배열 내 객체의 속성을 바꾸자 가정

1. id를 찾는다

2. id를 갖고 있는 그 객체의 속성을 바꾼다 ( 객체 속성 어떻게 바꿈 위에서 설명했습니다 {...prev, 바꿀 객체 속성 : 바꿀값})

3. 2번할때는 삼항연산자를 활용하여, id가 있으면 바꾸고 아님 말고 (if문 써도 괜찮겠네요)

const [todos, setTodos] = useState([
  { id: 1, text: "React 공부하기", completed: false },
  { id: 2, text: "운동하기", completed: false }
]);

// 특정 `id`를 가진 요소의 `completed` 값을 토글
const toggleTodo = (id) => {
  setTodos((prev) => 
    prev.map(todo => 
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    )
  );
};

 

 

숫자 혹은 문자열도 똑같이 prev 적용하십쇼

const [count, setCount] = useState(0);

// ✅ 카운트 증가
const increaseCount = () => {
  setCount((prev) => prev + 1);
};

// ✅ 카운트 감소
const decreaseCount = () => {
  setCount((prev) => prev - 1);
};

const [text, setText] = useState("Hello");

// ✅ 문자열 추가
const addExclamation = () => {
  setText((prev) => prev + "!");
};