개발공부/리액트

[리액트] 스터디 (git 포함)

햄❤️ 2021. 9. 18. 20:00
728x90

 ✨  useEffect dependency에 state로 인한 무한 렌더링을 야기하는 경우*(코드)

- 무한루프에 빠지는 경우를 먼저 알아야할 것 같다. 

 1) 의존성 배열이 없을 경우
 2) 의존성 배열이 있으나, useEffect 함수 내에서 의존성 배열 내의 값을 수정하고 있는 경우
 3) 의존성 배열이 있으나, useEffect내에서 state의 변경을 야기하는 경우

  const obj = {
    name: "amy",
    age:28
  }
  const [myInfo, setMyInfo] = useState({...obj});

  useEffect(()=>{
    setMyInfo({...myInfo, age:22});
  },[obj])

obj가 바뀌지 않았는데, 무한 렌더링이 발생한다.

이 이슈를 찾는데 사수님께서 알려주셨다. CS공부의 필요성이 절실하게 느껴졌다. 흑흑.. setMyInfo의 값이 바뀌었다. 바뀌면서 리렌더링이 된다. 리렌더링 될때 obj는 객체기 때문에 또 다른 객체가 생긴다. useEffect는 디펜던시안에 obj를 바라보고 있다가 변경되면 렌더링을 할 준비를 하는데, 객체가 다시 재 선언 되면서 새로운 객체가 되버린다. useEffect는 어? 바뀌었네 하고 계속..렌더링 무한 렌더링을 하게 되는 것이다. 

디펜던시에서 obj를 뺀다면? 무한 루프가 일어나지 않는다. 첫 렌더링에서 myInfo값을 바꿔주면 리렌더링 되지만, 빈배열이기 때문에 effect를 건더 뛴다. 그래서 무한 루프가 일어나지 않는다. 

그래서 useEffect 디펜던시에는 객체를 넣지 않는다. 디펜던시에는 state만 넣자... 후 오늘도 값진 것을 배웠다. 

그리고 useEffect를 올바르게 쓰는 방법? 만약 useEffect가 엄청 많은 컴포넌트에서, 내가 바꾸는 state가 다른 useEffect의 디펜던시일 수도 있기 때문에 꼭 확인해야한다. 그리고 useEffect는 쓰여진 순서대로 실행되니까 state가 바뀌는 흐름대로 위에서 아래로 짜는게 좋을 것 같다. 

이런것들의 기본이 되는 byte, bit, 객체, 주소 등 CS지식을 다음주에는 꼭 공부하도록 하자! ㅜㅜ

 

 ✨  react , 브라우저 렌더링 되는 과정(DOM 관련해서) 

 - DOM(Document Object Model) 은 브라우저 렌더링 엔진의 HTML parser에 의해 생성된 트리 구조의 Node 객체 모델이다.

 - DOM의 목적은 JS를 사용해서 문서에 대한 추가/삭제/이벤트 처리하는 인터페이스를 제공하는 것 

 - 브라우저가 html을 받으면 파싱해서 DOM객체로 이루어진 DOM 트리를 만들고  렌더 트리를 만든다.
 렌더 트리를 구성하면, 각 노드들의 스크린 좌표가 주어지고 어디에 나타나야 할 지 레이아웃을 정한다. (동기적으로 발생)
 DOM에 변화가 생기면, 렌더트리가 다시 만들어지고 -> 레이아웃도 다시 정해진다. 

 - 성능저하의 원인: DOM 수정하면 발생하는 Reflow, Repaint 과정


 - ref의 .current값은 선택한 DOM을 가리킨다. default값은 선언할 때 () 안의 useRef(default) 지정한 값 

 - current속성은 값을 변경해도 상태를 변경할때처럼 리렌더링 되지 않는다. 컴포넌트가 다시 렌더링 될 때도 마찬가지로 current 속성의 값은 유실되지 않는다. 즉 렌더링 되지 않아도 바뀐 값을 바로 확인할 수 있다. (렌더링에 영향을 주지도, 받지도 않음) 

 - 렌더링이 필요하지 않은 state를 ref로 관리하는 방법도 있다.

 - react에서 Document.querySelector로 DOM을 선택하는 것은 리액트의 안티패턴 -> 컴포넌트 재활용할때 id 겹친다.

 - 근데... dom을 직접 조작하면ㅠ 렌더트리가 다시 만들어지고 레이아웃, 리페인트가 다시 되는데 렌더링이 왜 트리거 되지않는지 모르겠다. !!! 찾아도 안나와!!!!  

아래에 대한 글이 나의 질문에 대한 답이 될까....?

1. useRef() 는 일반적인 자바스크립트 객체입니다.

즉 heap 영역에 저장되는 변수입니다.

2.매번 렌더링할 때 동일한 객체를 제공합니다.

heap에 저장되어 있기 때문에 어플리케이션이 종료되거나 가비지 컬렉팅될 때 까지, 참조할때마다 같은 메모리 값을 가진다고 할 수 있습니다.

3.값이 변경되어도 리렌더링이 되지 않습니다.

같은 메모리 주소를 갖고있기 때문에 자바스크립트의 === 연산이 항상 true 를 반환합니다. 즉 변경사항을 감지할 수 없어서 리렌더링을 하지 않는다는 뜻입니다.

 

 ✨  git revert, reset의 차이(소스트리에서 어떻게 쓰는지 - 되돌리기? 이 커밋으로 초기화?)

 

   - reset은 특정 커밋으로 되돌아가고, 그 이후의 커밋들이 사라진다. 대신 커밋은 안 생긴다. 
   - revert는 특정 커밋을 없던 일로 만든다. 대신 revert를 했다는 커밋이 생긴다. 없애려는 특정 커밋이 다음 커밋과 연결되면 충돌이 난다. 

  - 이미 remote에 push한것은 reset은 안되고 revert만 가능하다. 내 로컬 git만 과거로 돌릴 수 있기 때문... 혼자 작업하는 브랜치라면 push --force로 연결하면 된다. 

  - but 공용 브랜치에서 git reset은 사용 안하는게 좋다. reset후 Push하면 내 로컬은 뒤로 돌아갔지만, 다른 작업자의 head는 reset되지 않았다. git pull을 해도 돌아가지지 않는다. 

 - 소스트리에서 되돌리기 -> revert!! , 이 커밋으로 초기화 -> reset!! 

 

어떤 블로거분이 만화로 이 차이점을 잘 그려놓으셨다.. 추천추천 

http://www.devpools.kr/2017/01/31/%EA%B0%9C%EB%B0%9C%EB%B0%94%EB%B3%B4%EB%93%A4-1%ED%99%94-git-back-to-the-future/

728x90