공식 React 문서로 세부 정보 수집 #7

문맥

문맥

  • 컨텍스트: 구성 요소 트리에서 데이터를 공유하는 방법입니다.
  • 컨텍스트를 사용하면 각 단계에서 소품을 전달하지 않고도 구성 요소 트리 전체에 데이터를 제공할 수 있습니다.
  • 컨텍스트를 사용하는 경우
    • 컨텍스트는 React 구성 요소 트리 내에서 전역으로 간주될 수 있는 데이터를 공유하는 방법입니다.
    • 이 데이터에는 현재 로그인한 사용자, 테마선호하는 언어 등.
  • 구성 요소 조립은 여러 수준에서 전달되는 소품을 대체하는 컨텍스트보다 간단한 솔루션이 될 수 있습니다.

핫키

rcc 탭(반응 등급 구성요소)
rfc 탭(반응 함수 구성 요소)

구성 요소 트리 제약 조건 > 기둥 드릴링 제약 조건 해결
재사용성 > 컨텍스트를 사용할 때 재사용하기 어려움
API > createContext/제공자/소비자
userContext > 소비자 재정의

  • DOM 계층 외부의 DOM 노드에서 자식을 렌더링하기 위한 모범 사례

  • 포털
    • createPortal > 상위 구성 요소의 DOM 구조에서 벗어나기
    • 이벤트 > 포털에 있는 경우에도 이벤트가 트리 위로 전파됩니다.

렌더링 소품

  • 재사용 방법(렌더링 컴포지션/HOC/소품)

렌더링 소품

  • 함수 소품을 사용하여 React 구성 요소 간에 코드를 공유하는 간단한 기술입니다.

Render Props > 무엇을 렌더링할지 지정하는 함수
렌더링할 필요가 없습니다. 어린아이든 상관없습니다.
PureComponent > Props, State와 비교하여 성능 최적화

중간보고

문맥

구성 요소 트리 제약 – 드릴링 소품에 대한 제약 제거
재사용성: 컨텍스트를 사용할 때 재사용하기 어려움
API: createContext/제공자/소비자
useContext : 소비자 재정의

포털

createPortal > 상위 구성 요소의 DOM 구조에서 벗어나기
Events > Portal에 있더라도 이벤트가 트리 위로 전파됩니다.

렌더링 소품

render props : 무엇을 렌더링할지 알려주는 함수
렌더링할 필요가 없습니다. 아이가 되든 뭐든
PureComponent > Props, State를 비교하여 성능 최적화

주변에서 번성하는 사람의 자질은 무엇입니까?

나는 개발을 매우 좋아합니다. (새로운 것에 대한 열망)
책임감이 강합니다.
상식(게으름 + 일)
루트로 이동(이유에 대한 답을 알고 있는지 확인하십시오.)

가장 좋은 사람은 책임감을 가지고 뿌리까지 파고드는 사람입니다.

React propTypes를 사용한 유형 검사

PropTypes를 사용한 유형 검사 – React

사용자 인터페이스 구축을 위한 JavaScript 라이브러리

www.reactjs.org

소품 유형

  • 소품 유형을 확인하는 도구(flow, typescript와 같은 정적 작성 도구)
  • 개발 모드에서만 작동 => 잘못된 소품 경고
  • custom => RegExp 등으로 사용자 정의 가능
  • 아동 제한 => 원래 무제한 제한 가능
유형을 확인하고 오류를 사전에 포착합니다.
import PropTypes from "prop-types";

MyComponent.propTypes = {
  // prop가 특정 JS 형식임을 선언할 수 있다.
  // 이것들은 기본적으로 모두 선택 사항이다.
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // 랜더링 될 수 있는 것들은 다음과 같다.
  // 숫자(numbers), 문자(strings), 엘리먼트(elements), 또는 이러한 타입들(types)을 포함하고 있는 배열(array) (혹은 배열의 fragment)
  optionalNode: PropTypes.node,

  // React 엘리먼트.
  optionalElement: PropTypes.element,

  // React 엘리먼트 타입 (ie. MyComponent)
  optionalElementType: PropTypes.elementType,

  // prop가 클래스의 인스턴스임을 선언할 수 있다.
  // 이 경우 JavaScript의 instanceof 연산자를 사용한다.
  optionalMessage: PropTypes.instanceOf(Message),

  // 열거형(enum)으로 처리하여 prop가 특정 값들로 제한되도록 할 수 있다.
  optionalEnum: PropTypes.oneOf(("News", "Photos")),
  // News와 photos 둘중 하나여야 한다.

  // 여러 종류중 하나의 종류가 될 수 있는 객체
  optionalUnion: PropTypes.oneOfType((PropTypes.string, PropTypes.number, PropTypes.instanceOf(Message))),

  // 특정 타입의 행렬
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // 특정 타입의 프로퍼티 값들을 갖는 객체
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // 특정 형태를 갖는 객체
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),

  // 추가 프로퍼티에 대한 경고가 있는 객체
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number,
  }),

  // 위에 있는 것 모두 `isRequired`와 연결하여 prop가 제공되지 않았을 때
  // 경고가 보이도록 할 수 있다.
  requiredFunc: PropTypes.func.isRequired,

  // 모든 데이터 타입이 가능한 필수값
  requiredAny: PropTypes.any.isRequired,

  // 사용자 정의 유효성 검사기를 지정할 수도 있다.
  // 검사 실패 시에는 에러(Error) 객체를 반환해야 한다.
  // `oneOfType`안에서는 작동하지 않으므로 `console.warn` 혹은 throw 하지 말기.
  customProp: function (props, propName, componentName) {
    if (!/matchme/.test(props(propName))) {
      return new Error("Invalid prop `" + propName + "` supplied to" + " `" + componentName + "`. Validation failed.");
    }
  },

  // `arrayOf` 와 `objectOf 에 사용자 정의 유효성 검사기를 적용할 수 있다.
  // 검사 실패 시에는 에러(Error) 객체를 반환해야 한다.
  // 유효성 검사기는 배열(array) 혹은 객체의 각 키(key)에 대하여 호출될 것이다.
  // 유효성 검사기의 첫 두 개의 변수는 배열 혹은 객체 자신과 현재 아이템의 키다.

  customArrayProp: PropTypes.arrayOf(function (propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue(key))) {
      return new Error(
        "Invalid prop `" + propFullName + "` supplied to" + " `" + componentName + "`. Validation failed."
      );
    }
  }),
};

한 아이만 부탁드립니다

  • PropTypes.element를 사용하여 하나의 하위만 구성 요소의 하위로 전파될 수 있도록 지정할 수 있습니다.
import PropTypes from "prop-types";

class MyComponent extends React.Component {
  render() {
    // 이것은 반드시 하나의 엘리먼트여야 한다. 아니라면, 경고(warn)가 일어날 것이다.
    const children = this.props.children;
    return <div>{children}</div>;
  }
}

MyComponent.propTypes = {
  children: PropTypes.element.isRequired,
};

초기 소품 값

  • defaultProps 속성을 할당하여 Props의 초기 값을 정의할 수 있습니다.
class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

// props의 초깃값을 정의한다.
Greeting.defaultProps = {
  name: "Stranger",
};

// "Hello, Stranger"를 랜더링 한다.
ReactDOM.render(<Greeting />, document.getElementById("example"));

class Greeting extends React.Component {
  static defaultProps = {
    name: "stranger",
  };

  render() {
    return <div>Hello, {this.props.name}</div>;
  }
}
  • defaultProps는 상위 구성 요소에서 지정하지 않은 경우 this.props.name의 값을 설정합니다.
  • propTypes는 defaultProps가 처리된 후에 유형이 검사되므로 defaultProps에도 적용됩니다.

기능성 부품

  • 펑션블록으로 개발하면
  • PropTypes를 적절하게 적용하기 위해 몇 가지 작은 변경을 수행할 수도 있습니다.
import PropTypes from "prop-types";

function HelloWorldComponent({ name }) {
  return <div>Hello, {name}</div>;
}

HelloWorldComponent.propTypes = {
  name: PropTypes.string,
};

export default HelloWorldComponent;
  • PropTypes를 추가하려면 아래와 같이 구성 요소를 노출하기 전에 별도의 함수로 선언할 수 있습니다.
  • 그런 다음 PropTypes를 HelloWorldComponent에 직접 추가할 수 있습니다.

반응 화해

화해

  • 실제 DOM과 가상 DOM을 동기화하는 것을 재조정이라고 합니다.
차이 알고리즘
  • 두 트리를 비교할 때 React는 루트 요소부터 비교합니다.
  • 후속 작업은 루트 요소의 유형에 따라 다릅니다.
다른 요소 유형
  • 두 개의 루트 요소가 다른 유형이면 React는 이전 트리를 버리고 완전히 새로운 트리를 만듭니다.
DOM 요소의 유형이 동일한 경우
  • 동일한 유형의 두 React DOM 요소를 비교할 때 React는 두 요소의 속성을 검사하고 동일한 히스토리를 유지하며 변경된 속성만 업데이트합니다.
  • 1. 클래스가 변경되는 경우
<div className="before" title="stuff" />

<div className="after" title="stuff" />
  1. 스타일이 바뀔 때
<div style={{color: 'red', fontWeight: 'bold'}} />

<div style={{color: 'green', fontWeight: 'bold'}} />
  • DOM 노드를 처리한 후 React는 해당 노드의 자식을 재귀적으로 처리합니다.
동일한 유형의 구성 요소
  • 구성 요소가 업데이트되면 인스턴스는 동일하게 유지되고 렌더링 간에 상태를 유지합니다.
  • React는 현재 구성 요소 인스턴스의 소품을 업데이트하여 새 요소의 내용을 반영합니다.
  • 이때 인스턴스의 UNSAFE_componentWillReceiveProps(), UNSAFE_componentWillUpdate() 및 componentDidUpdate가 호출됩니다.
  • 다음으로 render() 메서드가 호출되고 비교 알고리즘이 이전 결과와 새 결과를 재귀적으로 처리합니다.
자식의 재귀 처리
  • 기본적으로 DOM 노드의 자식을 재귀적으로 처리할 때 React는 두 목록을 동시에 반복하고 차이점이 있으면 변경합니다.
단추
<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
  1. 두 개의 트리에서 응답 <li>first</li>일치하는지 확인
  2. <li>second</li>일치하는지 확인하십시오.
  3. 그리고 마지막으로 <li>third</li>나무에.
  • 그러나 위와 같이 간단하게 구현하면 항목이 목록의 시작 부분에 추가될 때 성능이 저하됩니다.
  • 예를 들어 다음 두 가지 트리 변환은 제대로 작동하지 않습니다.
<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>
  • 반응하다 <li>Duke</li>그리고 <li>Villanova</li> 종속성 트리를 그대로 두지 않고 모든 자식을 수정합니다.
  • 이러한 비효율성은 문제가 될 수 있습니다.

열쇠

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>
  • 이 문제를 해결하기 위해 React는 key 속성을 지원합니다.
  • 자식에 키가 있으면 React는 키를 확인하여 원래 트리와 후속 트리의 자식이 일치하는지 확인합니다.
  • 위의 비효율적인 예를 수정하여 키를 추가하여 트리 변환을 보다 효율적으로 만들 수 있습니다.
  • children검색할 필요도 없고, 다른 것도 알아보고 빠르게 바꿀 수 있습니다.
  • 항목에는 일반적으로 식별자가 있으며 해당 데이터를 키로 사용할 수 있습니다.
<li key="{item.id}">{item.name}</li>
  • 그렇지 않은 경우 데이터 구조에 ID 속성을 추가하거나 데이터 조각을 해싱하여 키를 만들 수 있습니다.
  • 키는 전 세계적으로 고유하지 않고 형제 간에 고유해야 합니다.
  • 최후의 수단으로 배열 인덱스를 키로 사용할 수 있습니다.
  • 이 방법은 항목이 재정렬되지 않은 경우에는 잘 작동하지만 항목이 재정렬된 경우에는 비효율적입니다.
  • 인덱스를 키로 사용하는 동안 배열을 재정렬하면 구성 요소 상태에 문제가 발생할 수 있습니다.
  • 구성 요소 인스턴스는 키를 기반으로 업데이트되고 재사용됩니다.
  • 인덱스를 키로 사용하는 경우 요소의 순서가 변경되면 키도 변경됩니다.
  • 결과적으로 구성 요소의 상태가 엉망이 되거나 의도하지 않은 방식으로 변경될 수 있습니다.