항해 취업 리부트 코스 6기 (사전스터디)

Hunter Joe·2024년 10월 28일
0

항해99

목록 보기
3/7

React 숙련주차

reset css

크로스 브라우징 이슈를 해결하기 위한 css reset

  • 브라우저 (크롬, 파이어폭스, 브레이브, 오페라...)는 기본적으로 default style을 제공함 텍스트 크기, margin 등..

브라우저의 호환성을 위한 기본 스타일을 제거하기 위한 작업

아래 코드 외에도 reset css를 검색하면 다양하게 나옴

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

ref

  • ref를 이용해 해당 DOM요소 접근하기

페이지가 렌더링될 때 아이디 input 태그에 foucs가 됨

import { useEffect, useRef } from "react";
import "./App.css";

function App() {
  const idRef = useRef("");

  // 렌더링이 될 때
  useEffect(() => {
    idRef.current.focus();
  }, []);

  return (
    <>
      <div>
        아이디 : <input type="text" ref={idRef} />
      </div>
      <div>
        비밀번호 : <input type="password" />
      </div>
    </>
  );
}

export default App;

memoization

re-render의 발생 조건
1. 컴포넌트에서 state가 변경 될 때
2. 컴포넌트가 받아온 props가 변경 될 때
3. 부모 컴포넌트가 re-render된 경우 자식 컴포넌트도 re-render된다.

  • React에서 re-render가 빈번하게 일어난다 = 비용 발생
  • re-render를 최대한 줄인다 = 최적화 작업

불필요한 렌더링을 발생하지 않도록 최적화하는 대표적인 방법
1. memo(React.memo) : 컴포넌트를 캐싱
2. useCallback : 함수를 캐싱
3. useMemo : 값을 캐싱

캐싱 : 캐시는 컴퓨터 과학에서 데이터나 값을 미리 복사해 놓는 임시 장소

EX)

useCallback

memo가 컴포넌트를 memoization 했다면, useCallback()은 인자로 들어오는 함수 자체를 memoization 한다.

memo를 통해 Box1컴포넌트를 memoization 했음에도 re-render 발생
why? → 우리가 함수형 컴포넌트를 사용하기 때문이고 App.jsx가 리렌더링 되면서

const onInitButtonClickHandler = () => {
  initCount();
};

코드가 다시 만들어지기 때문입니다.

  • 자바스크립트에서는 함수도 객체의 한 종류에요. 따라서 모양은 같더라도 다시 만들어지면 그 주소값이 달라지고 이에 따라 하위 컴포넌트인Box1.jsx는 props가 변경됐다고 인식한다.
//App.jsx
// 변경 전
const initCount = () => {
  setCount(0);
};

// 변경 후
const initCount = useCallback(() => {
  setCount(0);
}, []);

useCallback()을 사용하고 나면 리렌더 방지

useCallback dependency

  • dependency에 값을 추가해서 해당 값 추적하기

 // count를 초기화해주는 함수
  const initCount = useCallback(() => {
	// !!Expected "[COUNT 변경] => 10에서 0으로 변경되었습니다."!!
    console.log(`[COUNT 변경] => ${count}에서 0으로 변경되었습니다.`);
    setCount(0);
  }, []);

현재 카운트가 10일 때 초기화 버튼을 누른다면
콘솔에 "[COUNT 변경] => 10에서 0으로 변경되었습니다."!!가 나타나길 기대함
그러나 예상과 다르게

COUNT 변경] => 0에서 0으로 변경되었습니다.라는 결과가 찍힌다.

이러한 이유는 useCallback()count가 0일 때 시점을 기준으로 메모리에 함수를 저장했기 때문이다. 이를 방지하려면 dependency에 count값을 추가하면 된다.

// count를 초기화해주는 함수
const initCount = useCallback(() => {
  console.log(`[COUNT 변경] ${count}에서 0으로 변경되었습니다.`);
  setCount(0);
}, [count]); //count추가

useMemo

  • useMemo(): value(값)을 캐싱한다.
  1. CASE 1에서는 onClick()을 실행할 때마다 count는 올라가지만, 매번 heavyWork() 함수가 다시 실행되기 때문에 딜레이 발생
    why?→ re-render될 때마다 heavyWork()가 실행되며, 이 함수는 100억 번의 연산을 수행하기 때문

  2. CASE 2에서 useMemo()를 사용하면 처음 렌더링할 때 한 번만 heavyWork()가 실행되고, 그 값이 memoization 된다.
    이후에는 dependency가 변경되지 않는 한 heavyWork()는 다시 실행되지 않음

Redux

  • 액션객체란, 반드시 type이란 key를 가져야 하는 객체이다. 또한 리듀서로 보낼 “명령"이다.
  • 디스패치란, 액션객체를 리듀서로 보내는 “전달자” 함수이다.
  • 리듀서란, 디스패치를 통해 전달받은 액션객체를 검사하고, 조건이 일치했을 때 새로운 상태값을 만들어내는 “변화를 만들어내는" 함수이다.
  • 디스패치(dispatch)를 사용하기위해서는 useDispatch() 라는 훅을 이용해야 한다.
    • 디스패치는 스토어의 내장함수 중 하나입니다.
    • 우선, 디스패치는 액션을 발생 시키는 것 정도로 이해하시면 됩니다.
    • dispatch 라는 함수에는 액션을 파라미터로 전달합니다.. dispatch(action) 이런식으로 말이죠.
  • 액션객체 type의 value는 대문자로 작성한다. (JS에서 상수는 대문자로 작성하는 룰이 있음)

Redux는 정리할것도 많았고 내가 헷갈려했던 내용이라 여기에 정리함

profile
두 or 다이 / FE 목표
post-custom-banner

0개의 댓글