简评:据作者说,练成绝招后副作用就是手会发红,屁股变坏。
所有你所需要知道的关于 React 的内容可以归结为 五个关键概念。
这五个关键概念就是:
- 组件
- JSX 语法
- 属性 & 状态
- 组件 API
- 组件类型
概念 #1: React 组件是如何工作的
你所需要了解的关于 React 的第一件事就是关于组件的事。你的 React 代码库就是一大堆大组件调用更小的组件。
什么是组件呢?组件完美的例子就是常见的 <select> HTML 元素。它不仅有视觉输出(灰色框,文字标签,向下的箭头组成了这个元素)——而且还处理自己的开闭逻辑。
现在想象用自己的样式和行为组建自定义的 <select> 元素。
那么,这恰恰就是 React 让你做的事。一个 React 组件是一个单一的对象,不仅输出像传统模板一样的 HTML,而且包括了控制该输出的所有代码。
在实践中,写 React 组件最为普遍的方式就是用 ES6 class 包含一个返回 HTML 的 render 方法(还有一个超级秘密的函数的方式,但你要等到第四个概念才能了解它):
class MyComponent extends React.Component {
render() {
return <p>Hello World!<p>;
}
}
概念 #2: JSX 是如何工作的
你可以看到,组件文件同时包含 HTML 和 JavaScript 代码。React 的秘密武器就是 JSX 语言(“X” 代表 “XML”)。JSX 可能一开始看起来很难对付,但你很快就能熟悉它。
我们都被教导要保持 HTML 和 JavaScript 的强大分离。但是当放松这个规则后,你能在你的前端产品中做一些惊奇的事。
比如,因为你现在拥有 JavaScript 的完整功能,你可以在 HTML 中使用 {...} 插入 JavaScript 片段来展示当前时间:
class MyComponent extends React.Component {
render() {
return <p>Today is: {new Date()}</p>;
}
}
这同样意味着你将使用纯 JavaScript for,if 语句或循环,而不是某种特定于模板的语法。JavaScript 的三元运算符在这里特别方便。
class MyComponent extends React.Component {
render() {
return <p>Hello {this.props.someVar ? 'World' : 'Kitty'}</p>;
}
}
顺带一提,作者推荐 ES6 语法,喜欢视频的可以看 ES6 for Everyone,喜欢阅读的可以看 Practical ES6。
概念 #3: 属性 & 状态 是如何工作的
可能你会想要知道上面的 this.props.someVar 变量是怎么来的。如果你写过一行 HTML,你可能熟悉 HTML 的属性比如<a>
标签的 href。在 React 中,属性表示为 props (properties 的缩写)。Props 是组件如何沟通的方式。
class ParentComponent extends React.Component {
render() {
return <ChildComponent message="Hello World"/>;
}
}
class ChildComponent extends React.Component {
render() {
return <p>And then I said, “{this.props.message}”</p>;
}
}
因为这个,React 的数据流是单向的。数据只能从父组件流向子组件,而不是相反的方式。
尽管有时候,一个组件做出反应的数据不是来自于父组件(比如用户输入)。这就是** state **怎么来的。
要理解 props 和 state 的不用之处,一个很好的比喻就是 Etch-A-Sketch 平板。与 Etch-A-Sketch 的身体颜色和拨号位置(props)不同,绘图(state)本身不是 Etch-A-Sketch 的固有属性,而仅仅是用户输入的临时结果。
注意组件的状态同样可以作为属性传递给它的子组件。你可以理解成一条大河从高山上流下来,随着路由,数据层,以及各种组件把它们的数据像小溪一样汇入,组成主要的 app 状态。
在组件中,状态用 setState 方法来管理,通常在事件处理器中调用。
class MyComponent extends React.Component {
handleClick = (e) => {
this.setState({clicked: true});
}
render() {
return <a href="#" onClick={this.handleClick}>Click me</a>;
}
}
在实践中,React 应用中大多数数据是属性。仅仅当你需要接收用户输入时,你需要用状态来处理变化。
注意到我们使用箭头函数来绑定 handleClick 处理器,你可以在这里学到更多。
概念 #4: 组件 API 是如何工作的
我们已经提到了 render 和 setState,两者都是组件 API 方法的一部分。另一个有用的是 constructor,你可以用来初始化你的状态和绑定方法。
除了这三个函数,React还提供了在组件生命周期(加载前,加载后,卸载后等等)内的各个点触发的一组回调。除非你做一些高级的 React 巫术,你将可能从不需要担心这些。
这节看起来很短,因为学习 React 实际上更多的是精通编程和架构的概念而不是学习一系列无聊的 API。它看起来如此清爽!
概念 #5: 组件类型是如何工作的
我们已经见识过如何使用类来定义一个组件:
class MyComponent extends React.Component {
render() {
return <p>Hello World!<p>;
}
}
并且我们还讨论了这些类支持的组件方法。现在忘掉它们!越来越多的人将 React 组件写成函数式组件。
一个函数式组件是一个函数,它使用 props 对象作为参数,并且返回一串 HTML。几乎就像一个传统的模板,关键的不同是在你需要的时候,你仍然可以在其中使用任何 JavaScript 代码:
const myComponent = props => {
return <p>Hello {props.name}! Today is {new Date()}.</p>
}
使用函数式组件语法的结果就是你失去了进入我们之前说的组件方法的权利。但事实证明,这是非常好的,因为绝大多数的组件可能不需要它们。
顺便一提,其中的一个方法是 setState,这意味着函数式组件不能有状态。因为这个原因,它们被通常被成为无状态函数组件。
由于函数式组件需要的样板代码少得多,尽可能使用它们是有意义的。因此,大多数 React 应用程序都包含两种语法的健康组合。
请注意还有第三个使用 createClass 函数的旧语法,任何使用它的人应该感到羞愧和被点名批评,因为大胆到使用 18 个月前的编程模式:
var Greeting = React.createClass({
render: function() {
return <h1>Hello, {this.props.name}</h1>;
}
});
其实有彩蛋,还有第六个概念,请戳原文:
原文链接:React’s Five Fingers of Death. Master these five concepts, then master React.
延伸阅读:
- JavaScript 数组和对象就像书和报纸一样
- 极光开源项目:「Aurora UI」,一个通用 IM 聊天 UI 组件,正在努力支持react中。