(2023/08/30)

React

  • ReactDOM => Web App 개발에 사용한다.
  • React Native => Mobile App 개발에 사용한다.

Strict Mode는 각 Component의 기능을 2번 호출하여, 순수 함수의 규칙을 위반하는 Component를 찾는 데 도움을 준다.
👉 Root Component<StrictMode>로 감싸서 사용한다.
👉 Strict Mode는 배포에 영향을 미치지 않는다.


실행 흐름

  1. Rendering Trigger
    👉 Component가 최초 실행될 때 Rendering을 지시한다.
    👉 상태 또는 속성이 변경되면 Rendering을 지시한다.
  2. Components Rendering
    👉 Component가 정의된 Function이 (다시) 실행된다.
  3. DOM Commit
    👉 ReactDOMJSX가 실제 DOMMount된다.
    👉 Mount된 이후, Callback Function으로 인해 Side Effects가 발생한다.
  4. Bronwser Painting
    👉 Browser를 그리는 단계이다.

최적화

  • React.memo를 통해 props가 변경되지 않은 Component리렌더링되는 것을 방지한다.

Component

마크업을 반환하는 JavaScript 함수
👉 Atomic Component는 상태를 가지지 않는 것이 좋다.

  • Componentreturn 전에는 불필요한 코드를 배치하지 않는다.
    👉 순수 함수
  • 함수로 정의되었지만, 함수()처럼 실행하지 않고 <이름></이름> 또는 <이름 />으로 실행한다.
    👉 하나의 매개변수인 props만 받는다.

선언된 Component 내부에 다른 Component가 선언되면 안 된다.
👉 Component를 파일별로 구분하여 최상위 수준에 작성한다.

Component의 네이밍은 항상 Pascal Case로 한다
👉 소문자로 시작하면, Function으로 인식한다.

  • createRootComponent를 담을 요소를 생성한다.
  • createRoot.render()render한다.
  • Component로 구성된 요소 안에 text를 넣으려면 props.children을 사용하여 rendering한다.

export | import

  • 이름으로 내보내기
export 함수

👉 불러오기

import { 이름 } from '경로'
  • 기본 내보내기
export default 함수

👉 불러오기

import 이름 from '경로'
  • 일반적으로 내보낼 Component가 하나인 경우에 기본 내보내기를 사용한다.
  • 이름으로 내보내기와 기본 내보내기는 { } 사용 여부의 차이가 있다.

JSX 마크업

React API로 작성하면 코드가 복잡하기 때문에 JavaScript의 확장인 JSX를 이용하여 HTML을 마크업한다.

BrowserJSX는 읽을 수 없다.
👉 Vite와 같은 도구를 이용하여 표준 JavaScript로 변환해야 Browser가 읽을 수 있다.

  • 형제 요소가 있다면,
    <div> 또는 <React.Fragment>와 같은 래퍼를 꼭 써서 내보내야 한다.
    👉 감싼 요소를 렌더링하지 않고자 할 때, <React.Fragment>를 사용한다.
    👉 <React.Fragment><>로 쓸 수 있다.
  • 한번 연 tag는 반드시 닫아줘야 한다.
    👉 <img>와 같이 닫는 태그가 없는 요소는 <img />처럼 닫아줘야 한다.
  • 속성의 이름은 Camel Case로 작성한다.
    👉 aria-, data--를 사용한다.
  • 변수에 할당된 것과 같이 동적으로 생성된 문자 값을 전달할 때에는 { } 안에 삽입한다.
    👉 JavaScipt의 객체는 { }로 표현되기 때문에, JavaScript의 객체를 삽입할 때에는 {{ }} 이중 중괄호가 된다.

상태

독립적인 비공개 데이터

상태는 최소한으로 만들어서 관리한다.

  • 상태를 여러가지를 만들기보다 파생된 상태를 만들어서 처리한다.
  • 상태를 그룹으로 묶어서 관리할 수도 있다.

상태 변수

React의 상태는 Snapshot 같아서,
Rendering Trigger로 인해 새로 리렌더링되지 않는 이상 상태 변수의 값은 절대 변경되지 않는다.
👉 useState Hook을 사용하여 상태 변수의 값을 변경시켜 리렌더링되도록 한다.

  • 상태변수는 같은 상태변경함수이더라도 각 Component마다 독립적으로 동작한다.
    👉 같은 상태변수를 다른 Component와 공유하고 싶을 때에는 상위 요소에 상태변수를 전달한다.
  • 상태변수는 상위 Component에서 접근/조작할 수 없다.

이벤트로 상태를 변경하고자 할 때는 set 함수를 함수에 담아서 전달해야 한다.
그렇지 않으면 무한 리렌더링 하게 된다.

상태 관리

value를 설정했을 경우

  • onChange Handlervalue를 변경할 수 있다.
  • defaultValue초깃값을 설정하여 변경할 수 있다.
    👉 defaultValue를 사용하면 명령형이기 때문에 외부 Event와 연결하기에 어려움이 있다.
  • readOnly를 설정하여 읽기전용으로 만들 수 있다.

객체와 배열인 상태는 원본이 훼손되지 않도록 복사해서 처리한다.

useState Hook 사용법

const [상태변수, 상태변경함수] = useState(초깃값);
/* 초깃값을 시작으로 상태변경함수가 실행될 때마다 상태변수가 리렌더링된다. */
/* useState Hook은 실행되면 상태변수와 상태변경함수를 요소로 가지는 배열이 반환되기 때문에,
   배열 구조 분해 할당을 이용하여 변수에 상태변수와 상태변경함수를 할당한다. */

상태변경함수(상태변수 + 1);  // 상태변경함수의 인수를 전달하여 상태변수의 값을 변경시킨다.
  • 상태변경함수set~으로 시작한다.
  • 상태변경함수의 인수로 업데이트 함수를 전달해서 한 번의 Rendering에 업데이트를 중첩시킬 수 있다.

List Rendering

  • .map() 등을 사용하여 배열을 렌더링하는 경우 key 설정이 필요하다.
    👉 cypto.randomUUID()를 이용하여 random key를 생성할 수 있다.
    👉 key 값은 고유해야 하나, 다른 배열의 key와는 동일해도 된다.
    👉 render할 때마다 key가 변경되면 render할 때마다 새로 생성하기 때문에, 성능 저하가 있다.
    👉 key는 최상위 요소에 붙인다.
    👉 key는 블록 내에서 한번만 사용한다.

Event Handling

Componentprops에 함수를 넘겨주고, JSX 요소의 속성으로 Event와 함수를 연결해준다.

function GotoButton({함수이름}) {
return <button onClick={함수이름}>버튼</button>
}

상위 Component에 연결된 경우에는 상위 Component의 속성에서 정의한다.

수많은 Event를 일일이 전달하기에는 번거롭기 때문에, 상위 Component에서 Event Function을 정의하고, 하위 Component에서는 Spread Syntax를 (...)를 이용하여 Event를 적용한다.


Side Effect

Side Effect는 일반적으로 Event Handler 연결에 속한다.

  • Event Handlerrendering되는 동안 실행되지 않기 때문에 순수할 필요가 없다.
  • useEffect Hook 내부에 있는 코드는 DOM Commit 단계 이후에 실행된다.
    👉 어떤 코드를 작성하더라도 Rendering에 영향을 주지 않기 때문에 순수 함수를 유지할 수 있다.

Hook

use로 시작하는 내장된 함수

  • Component의 최상단이나 use로 시작하는 함수의 최상단에서만 사용이 가능하다.
  • 내장된 함수 외에도 사용자가 커스텀할 수도 있다.

useEffect

Browser Painting 이후에 실행될 코드를 작성할 때 사용한다.
👉 try catch문을 이용하여 use(Layout)Effect 보다 좋게 지연된 처리를 할 수 있다.

useEffect Hook의 실행 시점을 조정하고 싶을 때

  • 종속성 배열이 없는 경우
    👉 항상 DOM Commit 이후에 실행된다.
  • 종속성 배열이 빈 배열인 경우
    👉 최초 DOM Commit 이후에 실행된다.
  • 종속성 배열에 상태를 요소로 넣은 경우
    👉 해당 상태가 변경되었을 경우의 DOM Commit 이후에만 실행된다.
  • useEffect가 중첩되지 않도록 CleanUp에 신경써야 한다.
    👉 useEffectreturnCleanUp Function을 작성한다.

useId

고유한 ID를 만들어준다.

useLayoutEffect

Animation을 적용할 때 사용하는 것이 적합하다.
👉 대신 성능이 저하될 수 있다.

DOM Commit 이후에 실행되기 때문에 useEffect보다 먼저 실행된다.
👉 애니메이션에 적합한 이유이다.

useCallback

useMemo와 동일하게 Rendering 간에 값을 기억하기 위해 사용한다.

useCallback(함수, 종속성배열)  // 종속성배열이 바뀔 때마다 함수의 값을 기억한다.

useCallback은 함수 값만 기억하고, useMemo는 함수를 포함한 모든 값을 기억한다.


Context

일반적으로 상위 요소에서 하위 요소로 state를 전달할 때 발생하는Props Drilling Issue를 방지하기 위해 사용한다.
👉 중첩된 요소를 모두 거치지 않고 바로 전달할 수 있도록 한다.

사용법

외부 contexts 폴더에 Context를 정의하여 사용한다.

읽기 전용

const 생성된컨텍스트 = createContext(초깃값);

useContext(생성된컨텍스트);
  1. 기본값에 상태를 전달하고 변수에 할당한다.
  2. useContext로 접근할 수 있다.

읽기/쓰기

const 생성된컨텍스트 = createContext();  // 빈 Context 생성
const [state, setState] = useState(초깃값);  // 상태 생성

<생성된컨텍스트.Provider
  displayName="확장프로그램에서 보여질 이름"
  value={state, setState}
>
/* 빈 Context에 생성한 상태를 공급하고, 내부 Component에서 해당 상태를 사용할 수 있다. */

  <사용할Component />

</...>
  1. Context를 생성한다.
  2. 상태를 생성한다.
  3. 생성한 Context 내부에서 사용할 상태와 하위 요소를 정의한다.

Refs

React Component Rendering에 영향을 주지 않으면서,
다음 Rendering에도 값을 기억하기 위한 수단이다.

DOM 요소에 접근할 때에도 사용된다.
👉 queryselector 등보다 신뢰할 수 있다.

useRefs(초깃값)  // Refs (참조 객체) 생성 => { current: 초깃값 }

애니메이션 구현하기

gsap을 이용하여 animation을 구현하려면,
useRef Hook을 사용하여 명령형으로 useLayoutEffecthandle function에서 사용한다.

사용법

useRef 객체를 생성한다.

const circleRef = useRef(null);  // { current: null }

JSX 요소에 Refs 객체를 전달한다

<figure
  ref={circleRef}  // 유일한 요소로 지정한다.
/>

useLayoutEffect 또는 Handle Function을 연결하여 사용한다.

useLayoutEffect(() => {
  gsap.set(circleRef.current, ...);
}
const handleEnter = (circleRef.current) => {
  gsap.to(circleRef.current, ...);
};

prop-types

prop-types를 이용하여 propstype을 검사하거나 지정해준다.

import { 내장메소드들 } from 'prop-types';

Component.propTypes = {
  부여된props1: 속성.isRequired  // '속성' 타입이어야 하고 필수값이다.
  부여된props2: arrayOf(속성)  // '속성'으로 구성된 배열이어야 한다.
  부여된props3: oneOf([속성1, 속성2])  // '속성1', '속성2' 중 하나여야 한다.
  부여된props4: shape({
    key1: 속성1,
    key2: 속성2
  })  // key1과 key2를 가지며, value의 속성은 각각 '속성1', '속성2'이다.
  부여된props5: exact({
    key1: 속성1,
    key2: 속성2
  })  // shape과 똑같지만, 다른 key는 추가할 수 없다.
}

.eslintrc.cjsignorePatternslinting하지 않을 것들을 정의할 수 있다.


react-helmet-async

Pagetitle을 설정하거나, Open Graph를 만들어준다.
👉 검색엔진 최적화에 도움이 된다.

사용법

<HelmetProvider>
  <하위컴포넌트>
    <Helmet>
      <title>이 페이지의 타이틀을 여기에 적습니다.</title>
    </Helmet>
  </하위컴포넌트>
</HelmetProvider>

Zustand

StateAction(동작 함수)을 함께 관리한다.

  • Context보다 코드가 적다.
  • State를 관리할 때 Context를 사용할 경우에는,
    State가 변경되면, Context.Provider 하위의 모든 요소가 re-Rendering되는데,
    Zustand를 사용하면, 불필요한 re-Rendering을 방지할 수 있다.

사용법

/* Store 만들고, Hook에 담기 */
const store이름 = (set) => ({  // Zustand에 set함수를 매개변수로 가지는 store를 생성한다.
  상태: 초깃값,
  액션: (매개변수) =>  // 상태를 변경할 함수를 액션이라고 한다.
    set((state) => ({
        상태를 변경할 코드
    }))
})
/* store는 상태와 상태를 변경할 함수(액션)을 가지는 함수이다. */

export const 커스텀훅 = create(store이름);  // store를 create하여 커스텀훅에 할당한다.
/* Hook을 불러와 상태 관리하기 */
const 변수 = ((state) => state.상태|액션);
/* State나 Action 중 사용할 것을 반환하는 콜백함수를 훅의 매개변수로 불러온다. */
/* 인수로 콜백함수를 전달해 성능 저하를 방지한다. */

/* ------------------------------------------------------------------ */

const { 상태, 액션, ... } = 커스텀훅((state) => {
  const { 상태, ...rest액션 } = state;

  return rest액션;
};
/* 하나씩 빼지 않고, 구조 분해 할당으로 한번에 불러올 수도 있다. */

persist를 사용하면 localstorage에 저장하여 새로고침해도 유지된다.

create(persist())

사용할 Component에서 커스텀훅(콜백함수)으로 State를 관리한다.


TanStack Query

한번 불러온 데이터를 캐싱하여 사용자의 경험을 높이기 위해 사용한다.

사용법

const 변수 = new QueryClient({});  // 객체 생성
/* 인수로 사용할 기능들을 넣어준다. */

<QueryClientProvider client={변수}>  // Component를 감싼다.
  <하위컴포넌트 />
<ReactQueryDevtools />  // 개발 툴 Component
</QueryClientProvider>

Next.js

  • index.html ➡️ layout.js
    (index.htmlBuild 시 생성된다.)
  • 공식 문서의 File Convention을 지켜야 한다.
  • Client인지 Server인지 구분하는 것이 핵심이다.
    ➡️ Client Fileuse client를 선언해야 한다.
profile
어제의 나보다 1% 발전하기💪

0개의 댓글