(本文未审核)javascript
目前为止,第二阶段知识已经基本介绍完,咱们已经具有了项目上手实战必备的 React.js 知识,如今能够把这些知识应用起来。接下来是实战环节,咱们会继续上一阶段的例子,把评论功能作得更加复杂一点。css
咱们在上一阶段的评论功能基础上加上如下功能需求:html
<code>
元素包含。例如输入 `console.log` 就会处理成 <code>console.log</code>
再显示到页面上。在线演示地址。java
你们能够在原来的第一阶段代码的基础上进行修改,第1、二阶段评论功能代码能够在这里找到: react-naive-book-examples。能够直接使用最新的样式文件 index.css 覆盖原来的 index.css。react
接下来能够分析如何利用第二阶段的知识来构建这些功能,在这个过程里面可能会穿插一些小技巧,但愿对你们有用。咱们回顾一下这个页面的组成:git
咱们以前把页面分红了四种不一样的组件:分别是 CommentApp
、CommentInput
、CommentList
、Comment
。咱们开始修改这个组件,把上面的需求逐个完成。github
这个功能是很简单的,咱们须要获取 textarea
的 DOM 元素而后调用 focus()
API 就能够了。咱们给输入框元素加上 ref
以便获取到 DOM 元素,修改 src/CommentInput.js
文件:浏览器
...
<textarea
ref={(textarea) => this.textarea = textarea} value={this.state.content} onChange={this.handleContentChange.bind(this)} /> ...
组件挂载完之后完成之后就能够调用 this.textarea.focus()
,给 CommentInput
组件加上 ComponentDidMount
生命周期:app
class CommentInput extends Component { static propTypes = { onSubmit: PropTypes.func } constructor () { super() this.state = { username: '', content: '' } } componentDidMount () { this.textarea.focus() } ...
这个功能就完成了。如今体验还不是很好,接下来咱们把用户名持久化一下,体验就会好不少。less
你们能够注意到咱们给原来的 props.onSubmit
参数加了组件参数验证,在此次实战案例中,咱们都会给评论功能的组件加上 propTypes
进行参数验证,接下来就不累述。
用户输入用户名,而后咱们把用户名保存到浏览器的 LocalStorage 当中,当页面加载的时候再从 LocalStorage 把以前保存的用户名显示到用户名输入框当中。这样用户就不用每次都输入用户名了,而且评论框是自动聚焦的,用户的输入体验就好不少。
咱们监听用户名输入框失去焦点的事件 onBlur
:
...
<input
value={this.state.username} onBlur={this.handleUsernameBlur.bind(this)} onChange={this.handleUsernameChange.bind(this)} /> ...
在 handleUsernameBlur
中咱们把用户的输入内容保存到 LocalStorage 当中:
class CommentInput extends Component { constructor () { super() this.state = { username: '', content: '' } } componentDidMount () { this.textarea.focus() } _saveUsername (username) { localStorage.setItem('username', username) } handleUsernameBlur (event) { this._saveUsername(event.target.value) } ...
在 handleUsernameBlur
中咱们把用户输入的内容传给了 _saveUsername
私有方法(全部私有方法都以 _
开头)。_saveUsername
会设置 LocalStorage 中的 username
字段,用户名就持久化了。这样就至关于每当用户输入完用户名之后(输入框失去焦点的时候),都会把用户名自动保存一次。
输入用户名,而后到浏览器里里面看看是否保存了:
而后咱们组件挂载的时候把用户名加载出来。这是一种数据加载操做,咱们说过,不依赖 DOM 操做的组件启动的操做均可以放在 componentWillMount
中进行,因此给 CommentInput
添加 componentWillMount
的组件生命周期:
...
componentWillMount () {
this._loadUsername() } _loadUsername () { const username = localStorage.getItem('username') if (username) { this.setState({ username }) } } _saveUsername (username) { localStorage.setItem('username', username) } ...
componentWillMount
会调用 _loadUsername
私有方法,_loadUsername
会从 LocalStorage 加载用户名而且 setState
到组件的 state.username
中。那么组件在渲染的时候(render
方法)挂载的时候就能够用上用户名了。
这样体验就好多了,刷新页面,不须要输入用户名,而且自动聚焦到了输入框。咱们 一、 2 需求都已经完成。
这里插入一些小贴示,你们能够注意到咱们组件的命名和方法的摆放顺序其实有必定的讲究,这里能够简单分享一下我的的习惯,仅供参考。
组件的私有方法都用 _
开头,全部事件监听的方法都用 handle
开头。把事件监听方法传给组件的时候,属性名用 on
开头。例如:
<CommentInput
onSubmit={this.handleSubmitComment.bind(this)} />
这样统一规范处理事件命名会给咱们带来语义化组件的好处,监听(on
)CommentInput
的 Submit
事件,而且交给 this
去处理(handle
)。这种规范在多人协做的时候也会很是方便。
另外,组件的内容编写顺序以下:
defaultProps
、propTypes
。constructor
。_
开头的私有方法。handle*
。render*
开头的方法,有时候 render()
方法里面的内容会分开到不一样函数里面进行,这些函数都以 render*
开头。render()
方法。若是全部的组件都按这种顺序来编写,那么维护起来就会方便不少,多人协做的时候别人理解代码也会一目了然。
由于第三方评论工具备问题,对本章节有任何疑问的朋友能够移步到 React.js 小书的论坛 发帖,我会回答你们的疑问。