문맥
- 컨텍스트: 구성 요소 트리에서 데이터를 공유하는 방법입니다.
- 컨텍스트를 사용하면 각 단계에서 소품을 전달하지 않고도 구성 요소 트리 전체에 데이터를 제공할 수 있습니다.
- 컨텍스트를 사용하는 경우
- 컨텍스트는 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를 비교하여 성능 최적화
주변에서 번성하는 사람의 자질은 무엇입니까?
나는 개발을 매우 좋아합니다. (새로운 것에 대한 열망)
책임감이 강합니다.
상식(게으름 + 일)
루트로 이동(이유에 대한 답을 알고 있는지 확인하십시오.)
가장 좋은 사람은 책임감을 가지고 뿌리까지 파고드는 사람입니다.
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" />
- 스타일이 바뀔 때
<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>
- 두 개의 트리에서 응답
<li>first</li>일치하는지 확인 <li>second</li>일치하는지 확인하십시오.- 그리고 마지막으로
<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 속성을 추가하거나 데이터 조각을 해싱하여 키를 만들 수 있습니다.
- 키는 전 세계적으로 고유하지 않고 형제 간에 고유해야 합니다.
- 최후의 수단으로 배열 인덱스를 키로 사용할 수 있습니다.
- 이 방법은 항목이 재정렬되지 않은 경우에는 잘 작동하지만 항목이 재정렬된 경우에는 비효율적입니다.
- 인덱스를 키로 사용하는 동안 배열을 재정렬하면 구성 요소 상태에 문제가 발생할 수 있습니다.
- 구성 요소 인스턴스는 키를 기반으로 업데이트되고 재사용됩니다.
- 인덱스를 키로 사용하는 경우 요소의 순서가 변경되면 키도 변경됩니다.
- 결과적으로 구성 요소의 상태가 엉망이 되거나 의도하지 않은 방식으로 변경될 수 있습니다.