일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 버전관리
- Map 인터페이스
- Method
- 이클립스
- Git
- 패키지
- java
- 이클립스 설치
- Collection Framework
- 깃
- GitHub
- 자바
- Eclipse
- 싱글톤 패턴
- Class
- 깃허브
- CSS
- 해결
- 인터페이스
- 컬렉션 프레임워크
- 클래스
- 메서드
- Collection 인터페이스
- html
- singlrton pattern
- 오류
- Today
- Total
안루피취뽀일기
조건적 콘텐츠 & State(상태) 업데이트 !매우간단하지만 중요한! 본문
Edit이라고 된 수정버튼을 누르면 <input>창이 뜨고
수정버튼에는 Save으로 바뀌어 저장버튼이 되어 그걸 또 누르면
다시 수정버튼이 되는
매우 간단하지만 저엉말 많이 쓰이는 그런 버튼을 구현하는데
머리로는 매우 간단할 것 같다는 생각이 들지요!
그렇다! 코드도 매우 간단하다!!!
하지만 알면 쉬운데 모르면 어려울 수 있는 고런거
아는게 힘!
import { useState } from "react";
export default function Player({ name, symbol }) {
const [isEditing, setIsEditing] = useState(false);
function handleEditClick() {
setIsEditing(isEditing ? false : true);
}
// let btnCaption = "Edit";
let playerName = <span className="player-name">{name}</span>;
if (isEditing) {
playerName = <input type="text" required value={name} />;
// btnCaption = "Save";
}
return (
<li>
<span className="player">
{playerName}
<span className="player-symbol">{symbol}</span>
</span>
<button onClick={handleEditClick}>{isEditing ? "Save" : "Edit"}</button>
</li>
);
}
setIsEditing(isEditing ? false : true);
=> isEditing이 지금 true이면 false로, false이면 true로 바꾸라는 간단한 삼항연산자.
허허 너무 쉽다 ㅎㅎ
하지만 ..!
더 간단한 방법이 있다는 거..
setIsEditing(!isEditing);
앞에 느낌표만 붙여주면 반전되지용~~~~~~~
그러나..
또 반전
이게 끝이 아니다
이러한 방식은 리액트에서 추천하지 않는다...!
새 State가 이전 State값에 따라 달라지는 경우 이와 같이 State를 업데이트해서는 안된다.
State를 이전 값에 기반하여 변경할 경우 함수를 하나 전달해야 하는데
해당 상태 변경 함수로 보내야 한다
왜 함수를 보내야 할까?
setIsEditing(( editing ) => !editing);
여기서 전달하는 이 함수를 리액트가 호출해서 자동적으로 현재 State값을 가지게 되게 때문이다.
즉 State 변경 전의 값이 입력된다.
매개변수를 하나 받는데, 이름은 editing으로 해주겠다.
이것또한 true 혹은 false인데, isEditing과 동일하다
하지만 editing 매개변수는 값으로 인식되어
리액트가 함수 호출 시 동적으로 설정 및 전달하게 된다!
이 함수를 setIsEditing으로 전달할 때 설정하고자 하는 새로운 State를 반환하게 된다.
setIsEditing(!isEditing);
그리고 아까 코드의 문제점 2
이 작업을 수행하는 리액트가 상태에 대한 변화의 스케줄을 조율한다는 점이다.
setIsEditing과 같은 상태 변경 함수를 통해 실행하고 있으니 두 단계로 이루어진다
즉 이 상태 변경은 즉각적으로 수행되는 것이 아니라 리액트가 미래에 수행하고자 상태 변경 스케줄을 조율하는 것이다
만약
function handleEditClick() {
setIsEditing(!isEditing);
setIsEditing(!isEditing);
}
이 코드가 실행된다면
setIsEditing을 true로 설정한 후 다시 false로 설정하기 때문에
아무 일도 일어나지 않을거라고 생각한다
그러나 대반전
예상한 결과와는 다르다
수정 버튼을 누르면 입력 창이 정상적으로 뜨고 저장을 누르면 사라진다
즉 이 결과는
function handleEditClick() {
setIsEditing(!isEditing);
}
이 두 번째 줄을 뺀 결과와 동일하다!!!!
이것이 함수 형태를 사용해야 하는 이유
리액트가 이 상태 변경 스케줄을 조율하는데 두 변화 모두 isEditing의 현재 상태를 기준으로 실행된다
function handleEditClick() {
setIsEditing(!isEditing);
setIsEditing(!isEditing);
}
즉 시작점은 false
그래서 setIsEditing(!isEditing); setIsEditing(!isEditing); 이 두줄 모두
isEditing이 false인 시점을 기준으로 한다
이 컴포넌트 함수가 처음 실행되는 시점에 isEditing의 값이 false이기 때문이다
setIsEditing을 isEditing의 반대격으로 호출할 때 상태 변경 스케줄을 조율하게 되는데
이때 setIsEditing을 true로 바꾸라는 명령이 즉각적으로 실행되지 않는다
그 다음 줄에서도 이전과 동일한 상태가 유지된다는 의미.
그 이유는 아직 동일한 컴포넌트 함수 실행의 사이클을 돌고 있기 때문이다
그리고 이 두 state 변화의 일정은 각자의 작업 이후에 실행된다
만약
function handleEditClick() {
setIsEditing((editing) => !editing);
setIsEditing((editing) => !editing);
}
이렇게 함수형으로 만든다면 이제야 내가 예상한 아무것도 일어나지 않는 상태가 되는 것이다!
함수 형태를 사용한다면 리액트가 보장해줄 수 있는 것은 이 state값은 언제나 가장 최신 버전이라는 점!
기억하자구!!!!!!!!!!
'React' 카테고리의 다른 글
양방향 바인딩 (0) | 2024.02.22 |
---|---|
State(상태)를 끌어올리면 안되는 경우 (0) | 2024.02.19 |
[S.WITH] 3일째 해결 못하고 있는 post_no undefined오류.. (0) | 2024.02.01 |
감싸진 요소에 Props(속성) 전달하기 (0) | 2024.01.29 |
[React] Todo List 만들기 (0) | 2023.12.28 |