React
是一个声明式,高效且灵活的拥有构建用户界面的 JS 库。主要书写的是 JS 代码,利用了 JSX 来实现模板,可以看作是插入到 JS 中的 Markdown Language。
组件
React 会将一些简短、独立的代码片段组合成复杂的 UI 界面。
组件类型
class Shop extends React.Component {
render() {
return (
<div className="shopping-list">
<h1> shopping list for {this.props.name} </h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
</ul>
</div>
);
}
}
// 用法:<Shop name="mark" />
其中,Shop 是一个 React 组件类,或者说是一个 React 组件类型。一个组件接受一些参数,我们把这些参数叫做 props。然后通过 render 方法返回需要显示在屏幕上的视图的层次结构。
render 方法返回值:一个 React 元素,描述了屏幕上需要显示的内容。
JSX 的目的就是为了减轻我们写模板的工作,它做的实际上是:将 <div> 编译成 React.createElement('div')。
从原理上看 JSX:
<div className="shopping-list">
<h1>Shopping List for {props.name}</h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
<li>Oculus</li>
</ul>
</div>;
实际上等于
/*#__PURE__*/
React.createElement("div", {
className: "shopping-list"
},
/*#__PURE__*/React.createElement("h1", null, "Shopping List for ", props.name),
/*#__PURE__*/React.createElement("ul", null,
/*#__PURE__*/React.createElement("li", null, "Instagram"),
/*#__PURE__*/React.createElement("li", null, "WhatsApp"),
/*#__PURE__*/React.createElement("li", null, "Oculus")
)
);
JSX 可以任意使用 JS 语句,只需要用大括号将该表达式包起来。
-
前文中的 Shop 组件中只渲染了一些内置的 DOM 组件,如
div、li等。但是我们也可以组合和渲染自定义的 React 组件,从而我们可以通过组合不同的 React 组件来实现复杂的 UI 界面。 -
React 元素被看作是 JS 中的一等公民中的对象(first-class JS object),因此我们可以将 React 元素作为参数来进行传递。
-
在 React 中,我们也可以用 React 元素的数组 来渲染多个元素。
React 中的 props.children
有点类似插槽的感觉,不过这时候的插槽变成了夹心饼干。
假设有一个 Foo 的大组件,以及两个 Baz 和 Bar 小组件。
const Foo = props => (
<div>
<p>I'm {Foo.name}</p>
<p>abc is: {props.abc}</p>
<p>I have {props.children.length} children.</p>
<p>They are: {props.children}.</p>
<p>{Array.isArray(props.children) ? 'My kids are an array.' : ''}</p>
</div>
);
const Baz = () => <span>{Baz.name} and</span>;
const Bar = () => <span> {Bar.name}</span>;
在使用(render/call/invoke) Foo 组件的时候,夹入了两个小组件,这两个小组件就是 Foo 大组件中的 props.children 了。
<Foo abc={123}>
<Baz />
<Bar />
</Foo>
输出为:
I'm Foo
abc is: 123
I have 2 children.
They are: Baz and Bar
My kids are an array.