React入门
React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。
参考资料
什么是JSX
render方法
- React.js中一切皆组件。一个组件类必须要实现一个 render 方法,这个 render 方法必须要返回一个 JSX 元素。但这里要注意的是,必须要用一个外层的 JSX 元素把所有内容包裹起来。返回并列多个 JSX 元素是不合法的
- 在 JSX 当中你可以插入 JavaScript 的表达式,表达式返回的结果会相应地渲染到页面上。表达式用 {} 包裹。
- 利用JSX可以增加一些逻辑性的东西,或者组合一些内容
- 自定义的组件都必须要用大写字母开头,普通的 HTML 标签都用小写字母开头。
- 通过在其它地方使用组件的标签,我们就可以插入一个组件,这样子在这个地方就会调用标签组件的render方法,非常利于组件的重复利用,多个不同的组件可以组成组件树(构建一个页面的逻辑)
- 为 React 的组件添加事件监听是很简单的事情,你只需要使用 React.js 提供了一系列的 on 方法即可。React.js 会给每个事件监听传入一个 event 对象,这个对象提供的功能和浏览器提供的功能一致,而且它是兼容所有浏览器的。React.js 的事件监听方法需要手动 bind 到当前实例,这种模式在 React.js 中非常常用。这些 on 的事件监听只能用在普通的 HTML 的标签上,而不能用在组件标签上。
- bind的作用:如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法 bind 到当前实例上再传入给 React.js。
state与props
- 一个组件的显示形态是由这个组件的数据状态(state)和配置参数(props)决定的
- state
- state 的主要作用是用于组件保存、控制、修改自己的可变状态。state 在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。你可以认为 state 是一个局部的、只能被组件自身控制的数据源。state 中状态可以通过 this.setState 方法进行更新,setState 会导致组件的重新渲染。
- setstate:setState 方法由父类 Component 所提供。当我们调用这个函数的时候,React.js 会更新组件的状态 state ,并且重新调用 render 方法,然后再把 render 方法所渲染的最新的内容显示到页面上。它接受一个对象或者函数作为参数。
- 当你调用 setState 的时候,React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新。
- 并不是每一次调用setState方法都会重新调用render方法,而是将对同一state的修改集合到一起再去同一渲染
- React中的setState方法:setState是异步执行的,所以需要一些方法来控制
- props
- props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props,否则组件的 props 永远保持不变
- 每个组件都可以接受一个 props 参数,它是一个对象,包含了所有你对这个组件的配置。
- 在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为 props 对象的键值
- React.js 也提供了一种方式 defaultProps,可以方便的做到默认配置。
- props 一旦传入进来就不能改变。
- 组件的使用者可以主动地通过重新渲染的方式把新的 props 传入组件当中,这样这个组件中由 props 决定的显示形态也会得到相应的改变。
React组件生命周期
- React
- JavaScript箭头函数
- bind,如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法 bind 到当前实例上再传入给 React.js。 相当于通过bind(this)来完成一个绑定当前实例的工作,方便在方法内调用实例的方法以及state状态或者props
- 挂载阶段的组件生命周期
- 挂载的概念:React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程称为组件的挂载
- 构建组件的生命周期
- -> constructor()
- -> componentWillMount()
- -> render()
- -> componentDidMount()
- 生命周期中的作用
- 我们一般会把组件的 state 的初始化工作放在 constructor 里面去做;
- componentWillMount:在 componentWillMount 进行组件的启动工作,例如 Ajax 数据拉取、定时器的启动;
- componentWillUnmount:组件从页面上销毁的时候,有时候需要一些数据的清理,例如定时器的清理,就会放在 componentWillUnmount 里面去做。
- componentDidMount: 一般来说,有些组件的启动工作是依赖 DOM 的,例如动画的启动,而 componentWillMount 的时候组件还没挂载完成,所以没法进行这些启动工作,这时候就可以把这些操作放在 componentDidMount 当中。
- 更新阶段的组件生命周期
- componentWillReceiveProps
- componentWillUpdate
- render
- componentDidUpdate
React渲染机制解析
- 渲染过程:在页面一开始打开的时候,React会调用render函数构建一棵Dom树,在state/props发生改变的时候,render函数会被再次调用渲染出另外一棵树,接着,React会用对两棵树进行对比,找到需要更新的地方批量改动。
- Diff算法:Diff算法只会对同层的节点进行比较。DOM结构介绍
- 假设1:两个相同的组件产生类似的DOM结构,不同组件产生不同DOM结构
- 假设2:对于同一层次的一组子节点,它们可以通过唯一的id区分
- 比较节点类型
- 节点类型相同
- DOM元素类型:只改变需要改变的属性
- React组件类型:触发更新过程
- shouldComponentUpdate
- componentWillReceiveProps
- componentWillUpdate
- render
- componentDidUpdate
- 节点类型不同:直接删除旧节点,创建新节点
- 节点类型相同
点赞按钮的例子
利用state存储状态例子
// 利用state存储状态
class LikeButton extends Component {
constructor () {
super()
this.state = { isLiked: false }
}
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
}
render () {
return (
<button onClick={this.handleClickOnLikeButton.bind(this)}>
{this.state.isLiked ? '取消' : '点赞'} 👍
</button>
)
}
}
维持组件可重复利用
class LikeButton extends Component {
constructor () {
super()
this.state = { isLiked: false }
}
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
}
render () {
// 设置了渲染的内容,方便后期更改
const likedText = this.props.likedText || '取消'
const unlikedText = this.props.unlikedText || '点赞'
return (
<button onClick={this.handleClickOnLikeButton.bind(this)}>
{this.state.isLiked ? likedText : unlikedText} 👍
</button>
)
}
}
利用props来重用组件
class Index extends Component {
render () {
return (
<div>
<LikeButton likedText='已赞' unlikedText='赞' />
</div>
)
}
}
如何设置默认值
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} 👍
</button>
)
}
}
This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://ahscuml.github.io/React入门/