Rendering Logic of React Child Elements
React source code
An interesting issue was discovered in React. Among the following four writing styles, only the first one will render “demo”:
Displays “demo”
const Demo = (props) => <div {...props} class="demo" />;
<Demo>demo</Demo>
Displays “hello”
const Demo = (props) => <div children="hello" class="demo" />;
<Demo>demo</Demo>
Doesn’t display any information
const Demo = (props) => <div class="demo" />;
<Demo>demo</Demo>
Doesn’t display any information
const Demo = () => <div class="demo" />;
<Demo>demo</Demo>
why?
The reason for the above behavior is due to the createElement
function.
function createElement(type, config, children) {
var propName = void 0;
// Reserved names are extracted
var props = {};
var key = null;
var ref = null;
var self = null;
var 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)) {
// here it will copy parent's children
props[propName] = config[propName];
}
}
}
// here if itself has children, it will overlap parent
var childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
var childArray = Array(childrenLength);
for (var i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
{
if (Object.freeze) {
Object.freeze(childArray);
}
}
props.children = childArray;
}
if (type && type.defaultProps) {
var defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
{
if (key || ref) {
var 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);
}