packages/react/ReactElement.js 해석
APIs
createElement
React.createElement(
type,
[props],
[...children]
)
지정된 유형의 React element를 생성하고 반환합니다.type 매개 변수는 탭 문자열 (예:
'div' 이나 'span', React component 구성 요소 (a class or a function), React fragment 형식일 수 있습니다.cloneElement
React.cloneElement(
element,
[props],
[...children]
)
복제하고 새로운react-element를 되돌려줍니다.반환된 새 reactElement에는 원래 요소의 속성이 있으며, 새로 부여된 속성은 원래 속성과 얕게 병합됩니다.새 서브어셈블리가 원래 서브어셈블리를 대체합니다.키와ref 속성이 보존됩니다.
React.cloneElement()는 다음과 같습니다.
{children}
그러나 이것도 구성 요소의ref를 보존합니다.이것은 리프를 통해 하위 노드를 얻을 때, 당신의 조상 노드에서 의외로 그것을 훔치지 않을 것이라는 것을 의미한다.같은 ref가 클론 후의 새 요소에 추가됩니다.
createFactory
React.createFactory(type)
지정된 유형의 React 요소를 생성하는 함수를 반환합니다.
React.createElement()와 비슷한 것은 형식 매개 변수는 탭 이름 문자열 (예: 'div' 이나 'span', React 구성 요소 형식 (class 구성 요소나 함수 구성 요소), React fragment 형식일 수도 있다.이 보조 함수는 사용되지 않으므로 JSX 또는 직접 호출
React.createElement()을 사용하여 대체하는 것이 좋습니다.isValidElement()
React.isValidElement(object)
객체가 React 요소인지 확인하고 반환 값이 true 또는 false인지 확인합니다.
소스 해석:
some utils:
import invariant from 'shared/invariant';
import warningWithoutStack from 'shared/warningWithoutStack';
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
import ReactCurrentOwner from './ReactCurrentOwner';
const hasOwnProperty = Object.prototype.hasOwnProperty;
const RESERVED_PROPS = {
key: true,
ref: true,
__self: true,
__source: true,
};
let specialPropKeyWarningShown, specialPropRefWarningShown;
function hasValidRef(config) {
if (__DEV__) {
if (hasOwnProperty.call(config, 'ref')) {
const getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.ref !== undefined;
}
function hasValidKey(config) {
if (__DEV__) {
if (hasOwnProperty.call(config, 'key')) {
const getter = Object.getOwnPropertyDescriptor(config, 'key').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.key !== undefined;
}
function defineKeyPropWarningGetter(props, displayName) {
const warnAboutAccessingKey = function() {
if (!specialPropKeyWarningShown) {
specialPropKeyWarningShown = true;
warningWithoutStack(
false,
'%s: `key` is not a prop. Trying to access it will result ' +
'in `undefined` being returned. If you need to access the same ' +
'value within the child component, you should pass it as a different ' +
'prop. (https://fb.me/react-special-props)',
displayName,
);
}
};
warnAboutAccessingKey.isReactWarning = true;
Object.defineProperty(props, 'key', {
get: warnAboutAccessingKey,
configurable: true,
});
}
function defineRefPropWarningGetter(props, displayName) {
const warnAboutAccessingRef = function() {
if (!specialPropRefWarningShown) {
specialPropRefWarningShown = true;
warningWithoutStack(
false,
'%s: `ref` is not a prop. Trying to access it will result ' +
'in `undefined` being returned. If you need to access the same ' +
'value within the child component, you should pass it as a different ' +
'prop. (https://fb.me/react-special-props)',
displayName,
);
}
};
warnAboutAccessingRef.isReactWarning = true;
Object.defineProperty(props, 'ref', {
get: warnAboutAccessingRef,
configurable: true,
});
}
RESERVED_PROPS 보존 속성: ReactElement을 구성할 때 config 파라미터에 보존 속성이 있으면 이 속성들은 단독으로 추출되어 파라미터로 별도로 전송됩니다ReactElement()hasValidRef와hasValidKey:config 매개 변수에 속성을 보존하는 두 가지 도구 방법이 있는지 판단합니다.defineKeyPropWarningGetter와defineRefPropWarningGetterref와 키라는 두 가지 특수한 속성에 대해react는 개발자가props에서 직접 가져오는 것을 허용하지 않으며 개발 환경에서 경고 로그를 보냅니다.핵심 API
/**
* Factory method to create a new React element. This no longer adheres to
* the class pattern, so do not use new to call it. Also, no instanceof check
* will work. Instead test $$typeof field against Symbol.for('react.element') to check
* if something is a React Element.
*
* @param {*} type
* @param {*} props
* @param {*} key
* @param {string|object} ref
* @param {*} owner
* @param {*} self A *temporary* helper to detect places where `this` is
* different from the `owner` when React.createElement is called, so that we
* can warn. We want to get rid of owner and replace string `ref`s with arrow
* functions, and as long as `this` and owner are the same, there will be no
* change in behavior.
* @param {*} source An annotation object (added by a transpiler or otherwise)
* indicating filename, line number, and/or other information.
* @internal
*/
const ReactElement = function(type, key, ref, self, source, owner, props) {
const element = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
};
if (__DEV__) {
// The validation flag is currently mutative. We put it on
// an external backing store so that we can freeze the whole object.
// This can be replaced with a WeakMap once they are implemented in
// commonly used development environments.
element._store = {};
// To make comparing ReactElements easier for testing purposes, we make
// the validation flag non-enumerable (where possible, which should
// include every environment we run tests in), so the test framework
// ignores it.
Object.defineProperty(element._store, 'validated', {
configurable: false,
enumerable: false,
writable: true,
value: false,
});
// self and source are DEV only properties.
Object.defineProperty(element, '_self', {
configurable: false,
enumerable: false,
writable: false,
value: self,
});
// Two elements created in two different places should be considered
// equal for testing purposes and therefore we hide it from enumeration.
Object.defineProperty(element, '_source', {
configurable: false,
enumerable: false,
writable: false,
value: source,
});
if (Object.freeze) {
Object.freeze(element.props);
Object.freeze(element);
}
}
return element;
};
ReactElement 함수는
ReactElement 대상을 정의하고 ReactElement 대상을 되돌려줍니다. 이 대상에는ref,key,props 등의 속성이 있습니다.또한 개발 환경에서는 개발자가 debug this 지침과 오류를 판단할 때 포지셔닝 코드를 추가하는 데 사용될 수 있습니다.추가 정의_self 속성이 일일이 열거할 수 없는 이유는 테스트를 할 때 테스트 용례를 쓰기 편하고 요소 대상을 동결할 수 있기 때문이다.createElement
/**
* Create and return a new ReactElement of the given type.
* See https://reactjs.org/docs/react-api.html#createelement
*/
export function createElement(type, config, children) {
let propName;
// Reserved names are extracted
const props = {};
let key = null;
let ref = null;
let self = null;
let source = null;
if (config != null) {
if (hasValidRef(config)) {
ref = config.ref;
}
if (hasValidKey(config)) {
key = '' + config.key;
}
self = config.__self === undefined ? null : config.__self;
source = config.__source === undefined ? null : config.__source;
// Remaining properties are added to a new props object
for (propName in config) {
if (
hasOwnProperty.call(config, propName) &&
!RESERVED_PROPS.hasOwnProperty(propName)
) {
props[propName] = config[propName];
}
}
}
// Children can be more than one argument, and those are transferred onto
// the newly allocated props object.
const childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
const childArray = Array(childrenLength);
for (let i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
if (__DEV__) {
if (Object.freeze) {
Object.freeze(childArray);
}
}
props.children = childArray;
}
// Resolve default props
if (type && type.defaultProps) {
const defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
if (__DEV__) {
if (key || ref) {
const displayName =
typeof type === 'function'
? type.displayName || type.name || 'Unknown'
: type;
if (key) {
defineKeyPropWarningGetter(props, displayName);
}
if (ref) {
defineRefPropWarningGetter(props, displayName);
}
}
}
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
_source 함수는 element._store.validated 세 개의 매개 변수를 받아들이고config는 createElement에 대해 특수 처리를 하며 보류된 속성을 추가 매개 변수로 전송type, config, children한다.또한 RESERVED_PROPS에 대해 ReactElement가 다중 파라미터인지 아닌지를 판단하고 여러 개children라면 수조로 부여children한다.cloneAndReplaceKey
export function cloneAndReplaceKey(oldElement, newKey) {
const newElement = ReactElement(
oldElement.type,
newKey,
oldElement.ref,
oldElement._self,
oldElement._source,
oldElement._owner,
oldElement.props,
);
return newElement;
}
원래 ReactElement을 복사합니다. 키를 바꿀 뿐입니다.
cloneElement
/**
* Clone and return a new ReactElement using element as the starting point.
* See https://reactjs.org/docs/react-api.html#cloneelement
*/
export function cloneElement(element, config, children) {
invariant(
!(element === null || element === undefined),
'React.cloneElement(...): The argument must be a React element, but you passed %s.',
element,
);
let propName;
// Original props are copied
const props = Object.assign({}, element.props);
// Reserved names are extracted
let key = element.key;
let ref = element.ref;
// Self is preserved since the owner is preserved.
const self = element._self;
// Source is preserved since cloneElement is unlikely to be targeted by a
// transpiler, and the original source is probably a better indicator of the
// true owner.
const source = element._source;
// Owner will be preserved, unless ref is overridden
let owner = element._owner;
if (config != null) {
if (hasValidRef(config)) {
// Silently steal the ref from the parent.
ref = config.ref;
owner = ReactCurrentOwner.current;
}
if (hasValidKey(config)) {
key = '' + config.key;
}
// Remaining properties override existing props
let defaultProps;
if (element.type && element.type.defaultProps) {
defaultProps = element.type.defaultProps;
}
for (propName in config) {
if (
hasOwnProperty.call(config, propName) &&
!RESERVED_PROPS.hasOwnProperty(propName)
) {
if (config[propName] === undefined && defaultProps !== undefined) {
// Resolve default props
props[propName] = defaultProps[propName];
} else {
props[propName] = config[propName];
}
}
}
}
// Children can be more than one argument, and those are transferred onto
// the newly allocated props object.
const childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
const childArray = Array(childrenLength);
for (let i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
props.children = childArray;
}
return ReactElement(element.type, key, ref, self, source, owner, props);
}
create Element과 유사하지만, 다른 것은 props에 대해 얕은 합병을 하는 것이다.
isValidElement
/**
* Verifies the object is a ReactElement.
* See https://reactjs.org/docs/react-api.html#isvalidelement
* @param {?object} object
* @return {boolean} True if `object` is a ReactElement.
* @final
*/
export function isValidElement(object) {
return (
typeof object === 'object' &&
object !== null &&
object.$$typeof === REACT_ELEMENT_TYPE
);
}
유효한 ReactElement 유형인지 판단합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.