React

Description: React와 관련된 기술, 경험등을 기록하는 카테고리입니다.

현재 노트: KR-010.20
하위 분류:

#React

useEffect를 사용하기전 정말 필요한지 생각해봐야 한다.

렌더링 최소화 하기

계획해 보기

테스트 해보기

Hook 변경하기전 분석하기

useEffect

cleanup 함수에서 raceCondtion을 방지하는 방법. 초기 ignore false, !ignore로 함수 실행, return ignore true로 unmount시 동작.

컴포넌트파일 이름규칙 대문자

컴포넌트는 다른 컴포넌트를 렌더링할 수 있지만, 그 정의를 중첩해서는 안 됩니다.

export default와 name export 사용시 고려사항

보편적으로 한 파일에서 하나의 컴포넌트만 export 할 때 default export 방식을 사용하고 여러 컴포넌트를 export 할 경우엔 named export 방식을 사용합니다. 어떤 방식을 사용하든 컴포넌트와 파일의 이름을 의미 있게 명명하는 것은 중요합니다. export default () => {} 처럼 이름 없는 컴포넌트는 나중에 디버깅하기 어렵기 때문에 권장하지 않습니다.

Fragment를 써야하는 이유

JSX는 HTML처럼 보이지만 내부적으로는 일반 JavaScript 객체로 변환됩니다. 하나의 배열로 감싸지 않은 하나의 함수에서는 두 개의 객체를 반환할 수 없습니다. 따라서 또 다른 태그나 Fragment로 감싸지 않으면 두 개의 JSX 태그를 반환할 수 없습니다.

모든 태그는 닫아주기

JSX에서는 태그를 명시적으로 닫아야 합니다. <img>처럼 자체적으로 닫아주는 태그는 반드시 <img /> 형태로 작성해야 하며, <li>oranges와 같은 래핑 태그도 <li>oranges</li> 형태로 작성해야 합니다.

거의 대부분 캐멀 케이스로!

JavaScript는 변수명에 제한이 있습니다. 예를 들면, 변수명에 대시를 포함하거나 class처럼 예약어를 사용할 수 없습니다. 이것이 바로 React에서 HTML과 SVG의 어트리뷰트 대부분이 캐멀 케이스로 작성되는 이유입니다. 예를 들면, stroke-width 대신 strokeWidth로 사용합니다. class는 예약어이기 때문에, React에서는 DOM의 프로퍼티의 이름을 따서 className으로 대신 작성합니다.

역사적인 이유로, aria-*data-*의 어트리뷰트는 HTML에서와 동일하게 대시를 사용하여 작성합니다.

prop의 기본값은 없거나 undefined일 때

기본값은 size prop이 없거나 size={undefined}로 전달될 때 사용됩니다. 그러나 size={null} 또는 size={0}으로 전달된다면, 기본값은 사용되지 않습니다.

컴포넌트 조건부 렌더링시 삼항 연산자

if (isPacked) {
  return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;

위와 같은 대신에 아래와 같이 작성

return (
  <li className="item">
    {isPacked ? name + ' ✅' : name}
  </li>
);

&&연산자로 조건부 렌더링시 왼쪽에 숫자는 놓으면 안된다

&&의 왼쪽에 숫자를 두지 마세요.

조건을 테스트하기 위해 JavaScript는 자동으로 왼쪽을 부울로 변환합니다. 그러나 왼쪽이 0이면 전체 식이 (0)을 얻게 되고, React는 아무것도 아닌 0을 렌더링할 것입니다.

화살표 함수의 암시적인 return 반환

화살표 함수는 암시적으로 => 바로 뒤에 식을 반환하기 때문에 return 문이 필요하지 않습니다.

const listItems = chemists.map(person =>
  <li>...</li> // 암시적 반환!
);

하지만 => 뒤에 { 가 오는 경우 return 을 명시적으로 반환해야합니다.

const listItems = chemists.map(person => { // 중괄호
  return <li>...</li>;
});

key 규칙

Key가 필요한 이유

React에 key가 필요한 이유는 무엇인가요?
데스크탑의 파일에 이름이 없다고 상상해 보세요. 대신 첫 번째 파일, 두 번째 파일 등 순서대로 파일을 참조할 것입니다. 익숙해질 수도 있지만, 파일을 삭제한다면 혼란스러워질 수도 있습니다. 두 번째 파일이 첫 번째 파일이 되고 세 번째 파일이 두 번째 파일이 되는 식으로 말이죠.

React 렌터 트리에 HTML 태그가 없는 이유

이러한 플랫폼 UI 기본 요소는 React의 일부가 아닙니다. React 렌더 트리는 앱이 렌더링되는 플랫폼에 관계없이 React 앱에 대한 통찰력을 제공할 수 있습니다.


HTML의 class대신 React에서는 className

JSX에서 중괄호를 통한 변수의 리터럴 방식 가능

Notice how onClick={handleClick} has no parentheses at the end! Do not call the event handler function: you only need to pass it down. React will call your event handler when the user clicks the button.

useState 문법

You’ll get two things from useState: the current state (count), and the function that lets you update it (setCount). You can give them any names, but the convention is to write [something, setSomething].

훅 사용 조건

Hooks are more restrictive than other functions. You can only call Hooks at the top of your components (or other Hooks). If you want to use useState in a condition or a loop, extract a new component and put it there.

pass down으로 내려주는 함수, 프로퍼티를 props라고한다

The information you pass down like this is called props.

index.js의 필수 항목들

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

React DevTools 사용해보기

일반적으로 컴포넌트 리팩토링시 상위 컴포넌트로 상태를 끌어올린다

Lifting state into a parent component is common when React components are refactored.

JavaScript supports closures which means an inner function (e.g. handleClick) has access to variables and functions defined in an outer function (e.g. Board). The handleClick function can read the squares state and call the setSquares method because they are both defined inside of the Board function.

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick() {
    const nextSquares = squares.slice();
    nextSquares[0] = "X";
    setSquares(nextSquares);
  }

  return (
    // ...
  )

prps를 미리 호출시 재 렌더링되며 infinite loop 문제 발생

<Square value={squares[0]} onSquareClick={handleClick(0)} />

중요한 것은 해당 함수가 call이 되는 것이고, 이에 따라 재렌더링됨.
해결방법은 화살표함수 형태로 변경. 즉 클릭이 될 때에만 call하게 변경

        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />

event handling 네이밍 규칭

The DOM <button> element’s onClick attribute has a special meaning to React because it is a built-in component. For custom components like Square, the naming is up to you. You could give any name to the Square’s onSquareClick prop or Board’s handleClick function, and the code would work the same. In React, it’s conventional to use onSomething names for props which represent events and handleSomething for the function definitions which handle those events.

props 전달시 onSomething
이벤트를 처리하는 함수 정의에 사용 handleSomething

불변성(immutablility)이 중요한 이유

뒤로가기와 같은 현재데이터를 취소하고 돌리는 일반적인 앱의 기능을 가능하게함
Immutability makes complex features much easier to implement. Later in this tutorial, you will implement a “time travel” feature that lets you review the game’s history and “jump back” to past moves. This functionality isn’t specific to games—an ability to undo and redo certain actions is a common requirement for apps. Avoiding direct data mutation lets you keep previous versions of the data intact, and reuse them later.

재 렌더링이의 코스트를 줄여줌
There is also another benefit of immutability. By default, all child components re-render automatically when the state of a parent component changes. This includes even the child components that weren’t affected by the change. Although re-rendering is not by itself noticeable to the user (you shouldn’t actively try to avoid it!), you might want to skip re-rendering a part of the tree that clearly wasn’t affected by it for performance reasons. Immutability makes it very cheap for components to compare whether their data has changed or not. You can learn more about how React chooses when to re-render a component in the memo API reference.

React에서의 Key값으로 렌더링, 재렌더링, 삭제 업데이트

Keys tell React about the identity of each component, which allows React to maintain state between re-renders. If a component’s key changes, the component will be destroyed and re-created with a new state.

동적 아이템을 만들 때 적절한 키의 중요성 강조
It’s strongly recommended that you assign proper keys whenever you build dynamic lists. If you don’t have an appropriate key, you may want to consider restructuring your data so that you do.

state의 조건 3가지

library 없이 자식 컴포넌트가 부모 컴포넌트 state 업데이트 하기

양방향 데이터흐름 자식에서 부모로 전달하기

You want to make it so whenever the user changes the form inputs, the state updates to reflect those changes. The state is owned by FilterableProductTable, so only it can call setFilterText and setInStockOnly. To let SearchBar update the FilterableProductTable’s state, you need to pass these functions down to SearchBar:

부모 컴포넌트의 state를 업데이트 하는 함수를 props로 전달하고, 자식 컴포넌트에서는 onChange 와 같은 이벤트 발생으로 해당 state를 업데이트함으로서 재렌더링 하게함