react注意点
event 对象
和普通浏览器一样,事件监听函数会被自动传入一个 event 对象,这个对象和普通的浏览器 event 对象所包含的方法和属性都基本一致。不同的是 React.js 中的 event 对象并不是浏览器提供的,而是它自己内部所构建的。React.js 将浏览器原生的 event 对象封装了一下,对外提供统一的 API 和属性,这样你就不用考虑不同浏览器的兼容性问题。这个 event 对象是符合 W3C 标准( W3C UI Events )的,它具有类似于event.stopPropagation、event.preventDefault 这种常用的方法。
我们来尝试一下,这次尝试当用户点击 h1 的时候,把 h1 的 innerHTML 打印出来:
class Title extends Component {
handleClickOnTitle (e) {
console.log(e.target.innerHTML)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle}>React 小书</h1>
)
}
}
再看看控制台,每次点击的时候就会打印”React 小书“。
关于事件中的 this
一般在某个类的实例方法里面的 this 指的是这个实例本身。但是你在上面的 handleClickOnTitle 中把 this 打印出来,你会看到 this 是 null 或者 undefined。
...
handleClickOnTitle (e) {
console.log(this) // => null or undefined
}
...
这是因为 React.js 调用你所传给它的方法的时候,并不是通过对象方法的方式调用(this.handleClickOnTitle),而是直接通过函数调用 (handleClickOnTitle),所以事件监听函数内并不能通过 this 获取到实例。
如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法 bind 到当前实例上再传入给 React.js。
class Title extends Component {
handleClickOnTitle (e) {
console.log(this)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle.bind(this)}>React 小书</h1>
)
}
}
bind 会把实例方法绑定到当前实例上,然后我们再把绑定后的函数传给 React.js 的 onClick 事件监听。这时候你再看看,点击 h1 的时候,就会把当前的实例打印出来:

你也可以在 bind 的时候给事件监听函数传入一些参数:
class Title extends Component {
handleClickOnTitle (word, e) {
console.log(this, word)
}
render () {
return (
<h1 onClick={this.handleClickOnTitle.bind(this, 'Hello')}>React 小书</h1>
)
}
}
这种 bind 模式在 React.js 的事件监听当中非常常见,bind 不仅可以帮我们把事件监听方法中的 this 绑定到当前组件实例上;还可以帮助我们在在渲染列表元素的时候,把列表元素传入事件监听函数当中——这个将在以后的章节提及。
如果有些同学对 JavaScript 的 this 模式或者 bind 函数的使用方式不是特别了解到话,可能会对这部分内容会有些迷惑,参考博客里面的this的详解。
setState 接受函数参数
这里还有要注意的是,当你调用 setState 的时候,React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新。这一点要好好注意。可以体会一下下面的代码:
...
handleClickOnLikeButton () {
console.log(this.state.isLiked)
this.setState({
isLiked: !this.state.isLiked
})
console.log(this.state.isLiked)
}
...
你会发现两次打印的都是 false,即使我们中间已经 setState 过一次了。这并不是什么 bug,只是 React.js 的 setState 把你的传进来的状态缓存起来,稍后才会帮你更新到 state 上,所以你获取到的还是原来的 isLiked。
所以如果你想在 setState 之后使用新的 state 来做后续运算就做不到了,例如:
...
handleClickOnLikeButton () {
this.setState({ count: 0 }) // => this.state.count 还是 undefined
this.setState({ count: this.state.count + 1}) // => undefined + 1 = NaN
this.setState({ count: this.state.count + 2}) // => NaN + 2 = NaN
}
...
上面的代码的运行结果并不能达到我们的预期,我们希望 count 运行结果是 3 ,可是最后得到的是 NaN。但是这种后续操作依赖前一个 setState 的结果的情况并不罕见。
这里就自然地引出了 setState 的第二种使用方式,可以接受一个函数作为参数。React.js 会把上一个 setState 的结果传入这个函数,你就可以使用该结果进行运算、操作,然后返回一个对象作为更新 state 的对象:
...
handleClickOnLikeButton () {
this.setState((prevState) => {
return { count: 0 }
})
this.setState((prevState) => {
return { count: prevState.count + 1 } // 上一个 setState 的返回是 count 为 0,当前返回 1
})
this.setState((prevState) => {
return { count: prevState.count + 2 } // 上一个 setState 的返回是 count 为 1,当前返回 3
})
// 最后的结果是 this.state.count 为 3
}
...
这样就可以达到上述的利用上一次 setState 结果进行运算的效果。
默认配置 defaultProps
上面的组件默认配置我们是通过 || 操作符来实现。这种需要默认配置的情况在 React.js 中非常常见,所以 React.js 也提供了一种方式 defaultProps,可以方便的做到默认配置。
class LikeButton extends Component {
static defaultProps = {
likedText: '取消',
unlikedText: '点赞'
}
constructor () {
super()
this.state = { isLiked: false }
}
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
}
render () {
return (
<button onClick={this.handleClickOnLikeButton.bind(this)}>
{this.state.isLiked
? this.props.likedText
: this.props.unlikedText}
react注意点的更多相关文章
- react组件的生命周期
写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...
- 十分钟介绍mobx与react
原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...
- RxJS + Redux + React = Amazing!(译一)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...
- React 入门教程
React 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内 ...
- 通往全栈工程师的捷径 —— react
腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...
- 2017-1-5 天气雨 React 学习笔记
官方example 中basic-click-counter <script type="text/babel"> var Counter = React.create ...
- RxJS + Redux + React = Amazing!(译二)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...
- React在开发中的常用结构以及功能详解
一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: impo ...
- React的使用与JSX的转换
前置技能:Chrome浏览器 一.拿糖:React的使用 React v0.14 RC 发布,主要更新项目: 两个包: React 和 React DOM DOM node refs 无状态的功能 ...
- Vue.js 2.0 和 React、Augular等其他框架的全方位对比
引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那么你就来对了. 客观来说,作为核心团队成员,显然我们会 ...
随机推荐
- Azure AD (5) 在单一目录下,使用Azure AD单点登录
<Windows Azure Platform 系列文章目录> 本文介绍的是,在单一目录下,使用Azure AD Connect,打通本地Domain Controller 我们需要准备的 ...
- JS-React:目录
ylbtech-JS-React:目录 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbt ...
- ++i和i++的效率孰优孰劣
在内建数据类型的情况下,效率没有区别: 在自定义数据类型的情况下,++i效率更高! 分析: (自定义数据类型的情况下) ++i返回对象的引用: i++总是要创建一个临时对象,在退出函数时还要销毁它,而 ...
- Ubuntu 安装杀毒软件防火墙
1.打开终端 2.输入sudo apt-get install clamtk 3.按照提示安装 4.安装完成后,输入clamtk 即可. 卸载方法: 1.打开终端 2.输入sudo apt-get a ...
- 【转载】“error LNK1169: 找到一个或多个多重定义的符号”的解决方法
c++的小细节的地方 原文地址:https://blog.csdn.net/xiaosu123/article/details/5665729 问题描述如下: 有 三个源文件,A.h.B.cpp.C. ...
- 构建Maven项目
Maven(一)如何用Eclipse创建一个Maven项目 Maven学习总结(三)——使用Maven构建项目 Eclipse创建一个Maven Web项目 [项目管理和构建]十分钟教程,eclips ...
- UVa 1645 Count (递推,数论)
题意:给定一棵 n 个结点的有根树,使得每个深度中所有结点的子结点数相同.求多棵这样的树. 析:首先这棵树是有根的,那么肯定有一个根结点,然后剩下的再看能不能再分成深度相同的子树,也就是说是不是它的约 ...
- Qt-MVC图形视图框架初识
使用QPushButton.QLabel.QCheckBox等构成GUI的控件或自定义图形时,开发应用程序会变得很简单.但是如果想在GUI中使用数十个或者数百个图形对象,向用户完美展示控制场景,则会受 ...
- [OpenGL]配置GLFW(超详细)
注:本文可转载,转载请著名出处:http://www.cnblogs.com/collectionne/p/6937644.html.本文还会修改,如果不在博客园(cnblogs)发现本文,建议访问上 ...
- E20180513-hm
letter n. 信; 证书,许可证; 字母,文字; 字面意义; bracket n. 支架,悬臂; 括弧; 类别,等级; [数] 同类项; coefficient n. 系数; (测定某种质量或 ...