웹게임 가위바위보
본 강의에서는 react의 component를 상속받은 class component를 사용한다.
React에서 extends Component 후 성능적 이슈가 있을지 react devtools로 확인 후 pure Component를 사용할지 결정
쓸데없이 리렌더링이 일어날 때는 pure Component로 전환한다.
background-postion을 통해 하나의 이미지의 부분부분을 재조명해준다
React life cycle
클래스 컴포넌트의 경우 -> constructor -> render -> ref (있을 경우) -> componentDidMount
-> (setState/props 의 값이 변경될 때 -> shouldComponentUpdate(true) -> render -> componentDidUpdate)
-> 부모 컴포넌트가 현재 컴포넌트 제거시 -> componentWillUnmount -> 컴포넌트 소멸
componentDidMount(){ } // 컴포넌트가 첫 렌더링된 후, 여기에 비동기 요청을 많이 한다.
componentDidUpdate(){ } // 리렌더링 후
componentWillUnmount(){ } // 컴포넌트가 제거되기 직전, 비동기 요청의 정리를 많이 한다.
** hooks 에는 라이프사이클 메소드가 없지만 useEffect가 라이프사이클 메소드의 역할을 해준다.
단 useEffect의 경우 두번째 인자값을 넣을 경우 해당 state의 변화감지시 컴포넌트 전체가 리렌더링 되기 때문에 주의해야한다.
useEffect(() => { // componentDidMount, componentDidUpdate 역할(1대1 대응은 아님)
interval.current = setInterval(changeHand, 100);
return () =>{ // 두번째 인자가 빈값일 때 componentWillUnmount 역할
clearInterval(interval.current)
}
}, [imgCoord]); // 두번째 인자가 있을때 componentDidMount 와 componentDidUpdate 둘 다 수행
** class 컴포넌트와 hooks 의 라이플사이클 비교
- useEffect는 [ ] 인자값으로 update될 state를 지정한다면,
클래스의 경우 componentDidMount나 componentDidUpdate에서 모든 state를 조건문으로 분기 처리한다.
(state 별로 처리 내용이 다르면 useEffect가 여러개가 될 수 있다.)
리액트 Hooks
useRef
- getElementById, querySelector 와 같이 특정 DOM을 선택해야되는 상황에서 사용
- 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리하는 역할
(변수값이 변해도 리렌더링되지 않음, 설정후 바로 조회가능)
[ 관리할수 있는 변수 ]
1. setTimeout, setInterval 을 통해서 만들어진 id
2. 외부 라이브러리를 사용하여 생성된 인스턴스
3. scroll 위치
[사용방법]
1. useRef() 를 사용하여 Ref 객체를 생성한다.
1-1. useRef() 를 사용 할 때 파라미터를 넣어주면, 이 값이 .current 값의 기본값이 된다.
2. 생성한 객체를 선택하고 싶은 DOM 에 ref 값으로 설정한다.
3. Ref 객체의 .current 값은 설정한 DOM 을 가르킨다.
4. Ref 객체의 값(.current)을 수정할 때에는 .current 값을 수정하고, 조회시에도 .current를 조회한다.
const nameInput = useRef();
const onClick = () => {
nameInput.current.focus();
}
const nextId = useRef(4);
const onCreate = () => {
// ...
nextId.current += 1;
};
return(
<input ref={nameInput} />
<button onClick={onClick}>클릭</button>
)
useLayoutEffect 와 useEffect 비교
useEffect
- 컴포넌트 렌더링 - 화면 업데이트 - useEffect실행
- 비동기적으로 실행됨
- DOM과 인터렉션이 없는 경우에 사용(대부분 경우)
useLayoutEffect
- 컴포넌트 렌더링 - useLayoutEffect 실행 - 화면 업데이트
- 동기적으로 실행됨
- 렌더링 직후 DOM요소의 값을 읽을 때 유용함(scroll position등)
- DOM을 mutate할 경우에 사용
useEffect를 사용할 경우 effect가 실행됨과 동시에 DOM에 mutation이 일어날 경우 flickering이 발생할 수 있다.
이러한 경우 useLayoutEffect를 사용해서 flickering(깜빡임)을 막을 수 있다.
결국 두 hook의 가장 큰 차이점은 실행 시점이고,
렌더링할 state가 이펙트 내에서 초기화되어야 할 경우, 사용자 경험을 위해 useLayoutEffect을 사용하는 편이 좋다.
고차 컴퍼넌트(Higher Order Component, HOC)
- HOC는 컴포넌트를 다른 컴포넌트로 감싸는 형태를 취하고 있고 컴포넌트를 인자로 받아 새로운 컴포넌트롤 다시 return한다.
- React.memo를 사용하면 PureComponent 역할을 한다.
React.memo
[작동기전]
- 컴퍼넌트가 React.memo()로 래핑 될 때, React는 컴퍼넌트를 렌더링하고 결과를 메모이징(Memoizing)한다.
- 다음 렌더링이 일어날 때 props가 같다면, React는 메모이징(Memoizing)된 내용을 재사용한다.
- 컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록 설정한다.
- 비슷한 역할을 하는 useCallback, useMemo, React.memo 는 렌더링 최적화로 컴포넌트의 성능을 실제로 개선할 때 사용한다.
- React.memo 에서 두번째 파라미터에 propsAreEqual 이라는 함수를 사용하여 특정 값들만 비교를 하는 것도 가능하다.
useMemo()
- 값을 메모이징해서 재사용한다.
- useMemo의 두번째 인자가 변경되면 초기화된다.
function NameTag(props) {
return useMemo( () => <div>{props.name}</div> , [props.name] )
}
useCallback()
- 함수 자체를 메모이징해서 재사용한다.
- useCallback의 두번째 인자가 변경되면 초기화된다.
- useCallback은 상하위 컴포넌트 관계에서 상위 컴포넌트가 넘겨주는 props를 핸들링하는 역할을 하는데,
하위 컴포넌트가 그 부분을 신경쓰지 않고 상위 컴포넌트의 렌더링 여부에 따라 자동으로 렌더링이 되면 무용지물이되기 때문에
React.memo 또는 useMemo와 함께 사용되어야한다.
const memoizedCallback = useCallback(
() => {doSomething(a,b);}, //inline callback
[a, b], //dependency
);
Hooks 사용 tip
1. hooks를 한번 선언하면 순서를 지켜주어야 한다.
따라서 조건문 안에는 절대 넣으면 안되고, 함수나 반복문, 다른 hooks 안에서 사용하면 안된다.
2. useEffect 패턴
useEffect(() => {
//ajax
}, []); //componentDidMount에서만 실행
const mounted = useRef(false);
useEffect(()=>{
if(!mounted.current){
mounted.current = true;
} else {
//ajax
}
}, [바뀌는 값]); //componentUpdate에서만 실행
출처 👇👇👇
라이프사이클 메소드 https://react.vlpt.us/basic/25-lifecycle.html
useRef https://react.vlpt.us/basic/12-variable-with-useRef.html
useLayoutEffect https://merrily-code.tistory.com/46
React.memo() https://ui.toast.com/weekly-pick/ko_20190731
강의정보 👇👇👇
플랫폼 : 인프런
강의 : 웹 게임을 만들며 배우는 React
강사 : 제로초(조현영)
개발환경 : vscode, react
'Programming > JavaScript' 카테고리의 다른 글
[Javascript] table에 동적으로 행(row), 열(column)추가, 삭제하기, td 너비 일정하게 유지하기 (0) | 2021.08.05 |
---|---|
[React ] Redux와 useReducer의 차이, Context API 사용하기 (0) | 2021.08.01 |
[React ] Webpack으로 React.js 빌드하기 (0) | 2021.07.25 |
[React / Node.js] 유튜브 사이트 클론코딩 - 에러 해결, React, ES6 문법 알아보기 (0) | 2021.07.18 |
[React / Node.js] react-router 리액트 라우터 알아보기 (0) | 2021.07.04 |