React 不会做任何静态分析来确定一个函数是否是一个组件。
相反,React 会做 “这是虚拟 DOM 的事情”
(以及所有其他魔法,如 lifecycles)
如果函数返回一个有效的 React 元素。
React 抛出一个错误,函数不返回 React 元素。
https://reactjs.org/docs/components-and-props.html:
这个函数是一个有效的 React 组件,因为它接受一个带有数据的“props”(代表属性)对象参数并返回一个 React 元素。我们将此类组件称为“函数组件”,因为它们实际上是 JavaScript 函数。
更详细...
从技术上讲,React 根本不需要任何函数或类组件。
使用函数
考虑这个例子,没有任何组件或功能:
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
React.createElement( 'div', null, [
React.createElement( 'h1', null, 'React without any functions' ),
React.createElement( 'p', null, 'Technically you don\'t need to pass functions to React.' ),
]),
document.getElementById('root')
);
这很快就会变得很麻烦。
因此,人们可能会想到通过使用将代码分成“部分”
返回这些部分的函数,例如:
const Headline = function(){
return React.createElement( 'h1', null, 'React with "factory functions"' );
};
const Content = function(){
return React.createElement( 'p', null, 'You might want to separate stuff using functions.' );
};
const Page = function(){
return React.createElement( 'div', null, [
Headline(),
Content()
]);
};
ReactDOM.render(
Page(),
document.getElementById('root')
);
请注意,这些只是普通的 javascript 函数,根本没有“魔法”。
如果你的函数没有返回一个有效的 ReactElement,那么 React 只会抛出一个错误,例如:
const Page = function(){
return { notAValidReactElement: 'this is not a valid react element' };
};
ReactDOM.render(
Page(), // ---> Uncaught Error: Objects are not valid as a React child ...
document.getElementById('root')
);
反应“组件”类型
但这不是最优的,例如所有.createElement() 方法仍然总是同时执行。
React 的人也有类似的想法,所以 React 接受一个函数名
作为 type 参数(而不是例如 'h1'),并像回调一样使用该函数,以便 React 可以决定例如如果函数
实际需要执行,也可以跳过:
const Page = function(){
return React.createElement( 'div', null, [
React.createElement( Headline, null, [] ),
React.createElement( Content, null, [] )
]);
}
这些仍然是和以前一样的功能。它们之所以起作用,是因为我们编写它们是为了让它们返回正确的值。
这实际上或多或少是关于这个主题的完整故事,但人们也可能对我为什么会感到困惑
谈论React.createElement( Page, ...,而我们通常使用<Page>...之类的东西。
所以...
JSX
有人可能会想到将React.createElement 缩短一点,以减少打字,例如:
const CE = function( type, props, childs ){
return React.createElement( type, props, childs );
};
ReactDOM.render(
CE( 'div', null, [
CE( 'h1', null, 'React without any functions' ),
CE( 'p', null, [
CE('b', null, 'Nice'),
' if we can shorten the code a bit.',
] ),
]),
document.getElementById('root')
);
幸运的是聪明人已经有了这个想法,所以你可以使用 JSX 来代替,例如:
ReactDOM.render(
<div>
<h1>React without any functions</h1>
<p>
<b>Even nicer: </b>
we can just use JSX!
</p>
</div>,
document.getElementById('root')
);
这只是一种不同的语法,它会在构建时转换为 javascript。