createElement 允许你创建一个 React 元素。此方法可作为 JSX. 的替代方案。

¥createElement lets you create a React element. It serves as an alternative to writing JSX.

const element = createElement(type, props, ...children)

参考

¥Reference

createElement(type, props, ...children)

调用 createElement 创建一个包含给定 typepropschildren 的 React 元素。

¥Call createElement to create a React element with the given type, props, and children.

import { createElement } from 'react';

function Greeting({ name }) {
return createElement(
'h1',
{ className: 'greeting' },
'Hello'
);
}

请参阅下面的更多示例。

¥See more examples below.

参数

¥Parameters

  • typetype 参数必须是有效的 React 组件类型。例如,它可以是一个标签名称字符串(例如 'div''span'),也可以是一个 React 组件(一个函数、一个类或一个像 Fragment 这样的特殊组件)。

    ¥type: The type argument must be a valid React component type. For example, it could be a tag name string (such as 'div' or 'span'), or a React component (a function, a class, or a special component like Fragment).

  • propsprops 参数必须是对象或 null。如果你传递 null,它将被视为空对象。React 会创建一个元素,其属性与你传递的 props 匹配。请注意,props 对象中的 refkey 是特殊的,在返回的 element 上将无法用作 element.props.refelement.props.key。它们将以 element.refelement.key 的形式提供。

    ¥props: The props argument must either be an object or null. If you pass null, it will be treated the same as an empty object. React will create an element with props matching the props you have passed. Note that ref and key from your props object are special and will not be available as element.props.ref and element.props.key on the returned element. They will be available as element.ref and element.key.

  • 可选 ...children:零个或多个子节点。它们可以是任何 React 节点,包括 React 元素、字符串、数字、portals、空节点(nullundefinedtruefalse)以及 React 节点数组。

    ¥optional ...children: Zero or more child nodes. They can be any React nodes, including React elements, strings, numbers, portals, empty nodes (null, undefined, true, and false), and arrays of React nodes.

返回

¥Returns

createElement 返回一个具有少量属性的 React 元素对象:

¥createElement returns a React element object with a few properties:

  • type:你已传递的 type

    ¥type: The type you have passed.

  • props:除 refkey 之外,你已传递的 props

    ¥props: The props you have passed except for ref and key.

  • ref:你已传递的 ref。如果缺失,则为 null

    ¥ref: The ref you have passed. If missing, null.

  • key:你已传递的 key,强制转换为字符串。如果缺失,则为 null

    ¥key: The key you have passed, coerced to a string. If missing, null.

通常,你会从组件中返回元素,或将其设为另一个元素的子元素。虽然你可以读取元素的属性,但最好在创建每个元素后将其视为不透明,并仅渲染它。

¥Usually, you’ll return the element from your component or make it a child of another element. Although you may read the element’s properties, it’s best to treat every element as opaque after it’s created, and only render it.

注意事项

¥Caveats

  • 你必须将 React 元素及其属性视为 不可变的,并且在创建后切勿更改其内容。在开发环境中,React 会浅显地 freeze 返回元素及其 props 属性以强制执行此操作。

    ¥You must treat React elements and their props as immutable and never change their contents after creation. In development, React will freeze the returned element and its props property shallowly to enforce this.

  • 使用 JSX 时,必须以大写字母开头的标签才能渲染你自己的自定义组件。换句话说,<Something /> 等同于 createElement(Something),但 <something />(小写)等同于 createElement('something')(注意它是一个字符串,因此它将被视为内置 HTML 标签)。

    ¥When you use JSX, you must start a tag with a capital letter to render your own custom component. In other words, <Something /> is equivalent to createElement(Something), but <something /> (lowercase) is equivalent to createElement('something') (note it’s a string, so it will be treated as a built-in HTML tag).

  • 只有当子组件都是静态已知的(例如 createElement('h1', {}, child1, child2, child3))时,才应将它们作为多个参数传递给 createElement。如果你的子组件是动态的,请将整个数组作为第三个参数传递:createElement('ul', {}, listItems)。这确保 React 将对任何动态列表进行 警告你缺少 key。对于静态列表,这不是必需的,因为它们永远不会重新排序。

    ¥You should only pass children as multiple arguments to createElement if they are all statically known, like createElement('h1', {}, child1, child2, child3). If your children are dynamic, pass the entire array as the third argument: createElement('ul', {}, listItems). This ensures that React will warn you about missing keys for any dynamic lists. For static lists this is not necessary because they never reorder.


用法

¥Usage

不使用 JSX 创建元素

¥Creating an element without JSX

如果你不喜欢 JSX 或无法在项目中使用它,你可以使用 createElement 作为替代方案。

¥If you don’t like JSX or can’t use it in your project, you can use createElement as an alternative.

要创建不使用 JSX 的元素,请使用一些 typepropschildren 参数调用 createElement

¥To create an element without JSX, call createElement with some type, props, and children:

import { createElement } from 'react';

function Greeting({ name }) {
return createElement(
'h1',
{ className: 'greeting' },
'Hello ',
createElement('i', null, name),
'. Welcome!'
);
}

children 是可选的,你可以根据需要传递任意数量的子元素(上面的示例有三个子元素)。此代码将显示带有问候语的 <h1> 标题。为了进行比较,以下是用 JSX 重写的相同示例:

¥The children are optional, and you can pass as many as you need (the example above has three children). This code will display a <h1> header with a greeting. For comparison, here is the same example rewritten with JSX:

function Greeting({ name }) {
return (
<h1 className="greeting">
Hello <i>{name}</i>. Welcome!
</h1>
);
}

要渲染你自己的 React 组件,请将像 Greeting 这样的函数作为 type 传递,而不是像 'h1' 这样的字符串:

¥To render your own React component, pass a function like Greeting as the type instead of a string like 'h1':

export default function App() {
return createElement(Greeting, { name: 'Taylor' });
}

使用 JSX,它看起来会像这样:

¥With JSX, it would look like this:

export default function App() {
return <Greeting name="Taylor" />;
}

这是一个使用 createElement 编写的完整示例:

¥Here is a complete example written with createElement:

import { createElement } from 'react';

function Greeting({ name }) {
  return createElement(
    'h1',
    { className: 'greeting' },
    'Hello ',
    createElement('i', null, name),
    '. Welcome!'
  );
}

export default function App() {
  return createElement(
    Greeting,
    { name: 'Taylor' }
  );
}

以下是使用 JSX 编写的相同示例:

¥And here is the same example written using JSX:

function Greeting({ name }) {
  return (
    <h1 className="greeting">
      Hello <i>{name}</i>. Welcome!
    </h1>
  );
}

export default function App() {
  return <Greeting name="Taylor" />;
}

两种编码风格都很好,因此你可以根据自己的项目选择一种。与 createElement 相比,使用 JSX 的主要好处是更容易区分结束标签和开始标签。

¥Both coding styles are fine, so you can use whichever one you prefer for your project. The main benefit of using JSX compared to createElement is that it’s easy to see which closing tag corresponds to which opening tag.

深入研究

React 元素究竟是什么?

¥What is a React element, exactly?

元素是对用户界面一部分的轻量级描述。例如,<Greeting name="Taylor" />createElement(Greeting, { name: 'Taylor' }) 都会生成如下对象:

¥An element is a lightweight description of a piece of the user interface. For example, both <Greeting name="Taylor" /> and createElement(Greeting, { name: 'Taylor' }) produce an object like this:

// Slightly simplified
{
type: Greeting,
props: {
name: 'Taylor'
},
key: null,
ref: null,
}

请注意,创建此对象不会渲染 Greeting 组件或创建任何 DOM 元素。

¥Note that creating this object does not render the Greeting component or create any DOM elements.

React 元素更像是一种描述 - 指示 React 稍后如何渲染 Greeting 组件。通过从你的 App 组件返回此对象,你可以告诉 React 下一步该做什么。

¥A React element is more like a description—an instruction for React to later render the Greeting component. By returning this object from your App component, you tell React what to do next.

创建元素非常便宜,因此你无需尝试优化或避免它。

¥Creating elements is extremely cheap so you don’t need to try to optimize or avoid it.