[React 완벽가이드] Section 4 : (tic tac toe 실습)

gonn-i·2024년 6월 1일
0

React 완벽 가이드

목록 보기
3/18
post-thumbnail

이미지 저장소 어디에 저장해야 하나? (public vs assets )

둘이 뭐가 다른데?

📁 public

public/ 에 저장하고 있는 이미지의 경우, 프로젝트 개발 서버 및 빌드 프로세스에 의해 공개적으로 제공된다. 따라서, 이 파일들은 브라우저 내에서 직접 방문이 가능하고, 파일에 의해 요청될 수 있음.

localhost:5173/image1.jpg 이렇게 불러오면 이미지를 볼 수 있음 (public/image1.jpg 이라면)

📁 src/assets

public과 asset으로 나눠보았지만, 사실상 publicsrc/assets 둘의 차이점에 주목해야 한다.
(꼭 이름이 assets일 필요는 없다. 다만,src/ 안에 위치해야 한다.)

아무튼, src/ 에 저장된 파일은 공개적으로 제공되지 않는다. 즉, 웹 방문자가 접근할 수 없다.
그대신, src/ 하위에 위치한 이미지들은 빌드 프로세스에 의해 인식되고 ➡️ public/ 에 삽입되어 웹단에 보여지게 된다. (이때, 참조한 위치에서 자동으로 링크가 생성됨)

그래서 언제 어떤 폴더를 사용하라고요? 🧐

1️⃣ 빌드 프로세스에 의해 처리되지 않는 이미지 ➡️ public/
ex. index.html 파일이나 파비콘에 사용되는 이미지)
2️⃣ 컴포넌트 내에서 사용되는 이미지 ➡️ src/(assets)

물론, 빌드 프로세스를 거치는 경우에도, public 폴더를 사용할 수 있으나, src/ 를 사용할 경우, 코드와 관련된 파일을 한곳으로 모아 유지 보수가 용이하다.

일반적으로는 public 폴더를 사용하고, 만일 컴포넌트에 사용될 경우 src/ 에 넣자


UseState

UseState: 이전 상태를 기반으로, 상태변화가 필요할때

토글이나, edit -> save 으로 버튼의 이름이 전환되는 경우가 여기에 해당하는데
이때 새로운 상태는, 이전의 상태값에 의존하게 된다 (on이면 => off로, edit -> save으로 동전의 양면과 같이 양자택일의 상황이기 떄문에 이전의 반대값을 취하게 됨)

이렇게 코드 짜기 ❌
setIsEditing(!isEditing)
-> 이경우 상태 변경은 즉각적으로 수행되지 않음
리액트가 미래에 수행하고자 하는 상태 변경 스케줄을 조율할 뿐
(몇 ms 겠지만, 즉각적이지 않다는 말 )

따라서, 경우에 따라 예상치 못한 결과를 얻을 수 있음

예시1

  function handleEdit() { //현재 isEditing가 false일 경우
    setIsEditing(!isEditing); // => isEditing를 true로 변경할 것을 스케쥴링
    setIsEditing(!isEditing); // => isEditing를 true로 변경할 것을 스케쥴링

  }

대신 아래와 같이 함수를 전달해주기. 이때 함수는 이전의 상태값을 전달해준다.
이말은 즉슨 함수식을 전달함으로써, 리액트가 바로 이전의 상태값을 매개변수로 전달해줄 것을 보장받는다!
setIsEditing(wasEditing => !wadEditing)

예시2

  function handleEdit() { //현재 isEditing가 false일 경우
    setIsEditing(!isEditing); // => isEditing를 true로 변경할 것을 스케쥴링
    setIsEditing(!isEditing); // => isEditing를 false로 변경할 것을 스케쥴링

  }

useState: 객체 상태를 변화시킬 때는, 복제 ➡️ 복제 버전 수정

🥸 왜 그렇게 하는데요?

배열이나 객체는 자바스크립트 내의 참조 값. (메모리 주소를 참조)
그러나 객체의 일부분을 직접 덮어써서 저장한다면, 이는 메모리 속의 기존값을 바로 변경하게 되는데
이 때문에, side effect가 생길 수 있음
(상태 업데이트가 여러개 예정되어 있을때 -> 원본 참조를 공유하는 모든 값이 영향을 받아, 알 수 없는 버그나 부작용이 생길 수 있음)

특정 상태가 객체나 배열에 영향을 받는다면 불변한 방식으로 변경되어야 함

❌ 배열에 직접적으로 접근하여 수정한 잘못된 경우 ❌

  function handleSelectSquare(rowIndex, colIndex, playerSymbol) {
    setGameBoard((prevGameBoard) => {
      prevGameBoard[rowIndex][colIndex] = 'X';
      return prevGameBoard;
    });
  }

따라서, 객체나 배열 (둘다 객체이긴 함)일때는, 이를 복제한 후, 원본을 참조하지 않는 복제된 값의 상태를 변화시켜주어야 한다. 상태를 변경 불가능한 방식으로 업데이트

⭕️ 불변한 방식으로 객체의 상태를 관리 ⭕️

  function handleSelectSquare(rowIndex, colIndex, playerSymbol) {
    setGameBoard((prevGameBoard) => {
      const updatedBoard = [...prevGameBoard.map((innerArray) => [...innerArray])];
      updatedBoard[rowIndex][colIndex] = 'X';
      return  updatedBoard;
    });
  }

state 끌어올리기

컴포넌트1과 컴포넌트2에서 같은 상태값을 다루어야 할때, 우리는 그 둘의 가장 가까운 부모 컴포넌트에서 해당 상태를 관리한다

0개의 댓글