ReactJS 组件
React 提倡组件化的开发方式,每个组件只关心自己部分的逻辑,使得应用更加容易维护和复用。
React 还有一个很大的优势是基于组件的状态更新视图,对于测试非常友好。
数据模型
state
React 每一个组件的实质是状态机(State Machines),在 React 的每一个组件里,通过更新 this.state,再调用 render() 方法进行渲染,React 会自动把最新的状态渲染到网页上。
1 | class HelloMessage extends React.Component { |
通过在组件的 constructor 中给 this.state 赋值,来设置 state 的初始值,每当 state 的值发生变化, React 重新渲染页面。
注意:
(1) 请不要直接编辑 this.state,因为这样会导致页面不重新渲染
1 | // Wrong |
使用 this.setState() 方法来改变它的值
1 | // Correct |
(2) this.state 的更新可能是异步的(this.props 也是如此)
React 可能会批量地调用 this.setState() 方法,this.state 和 this.props 也可能会异步地更新,所以你不能依赖它们目前的值去计算它们下一个状态。
比如下面更新计数器的方法会失败:
1 | // Wrong |
第二种形式的 setState() 方法接收的参数为一个函数而不是一个对象。函数的第一个参数为 previous state,第二个参数为当前的 props
1 | // Correct |
实现一个计数器
1 | class HelloMessage extends React.Component { |
props
React 的数据流是单向的,是自上向下的层级传递的,props 可以对固定的数据进行传递。
1 | class Welcome extends React.Component { |
state vs props
state 和 props 看起来很相似,其实是完全不同的东西。
一般来说,this.props 表示那些一旦定义,就不再改变的特性,比如购物车里的商品名称、价格,而 this.state 是会随着用户互动而产生变化的特性,比如用户购买商品的个数。
获取 DOM
在 React 中,我们可以通过 this.refs 方便地获取 DOM:
1 | class HelloMessage extends React.Component { |
生命周期
React 组件的生命周期分为三类:
(1) 挂载(Mounting): 已插入真实 DOM
componentWillMount(): 在初次渲染之前执行一次,最早的执行点
componentDidMount(): 在初次渲染之后执行
getInitialState() –> componentWillMount() –> render() –> componentDidMount()
(2) 更新(Updating): 正在被重新渲染
componentWillReceiveProps(): 在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。
shouldComponentUpdate(): 在接收到新的 props 或者 state,将要渲染之前调用。
componentWillUpdate(): 在接收到新的 props 或者 state 之前立刻调用。
componentDidUpdate(): 在组件的更新已经同步到 DOM 中之后立刻被调用。
componentWillReceiveProps() –> shouldComponentUpdate() –> componentWillUpdate –> render() –> componentDidUpdate()
(3) 移除(Unmounting): 已移出真实 DOM
componentWillUnmount(): 在组件从 DOM 中移除的时候立刻被调用。
下面举 React 官网的一个输出时间的例子,在 Clock 渲染之前设置一个定时器,每隔一秒更新一下 this.state.date 的值,并在组件移除的时候清除定时器。
1 | class Clock extends React.Component { |
事件
React 内建的跨浏览器的事件系统,我们可以在组件里添加属性来绑定事件和相应的处理函数。这种事件绑定方法极大的方便了事件操作,不用再像以前先定位到 DOM 节点,再通过 addEventListener 绑定事件,还要用 removeEventListener 解绑。当组件注销时,React 会自动帮我们解绑事件。
React 处理事件与 DOM 处理事件非常相似,有以下两点不同:
- React 事件用驼峰命名法,而不是全小写
- 通过 JSX 语法传递函数作为事件处理器,而不是字符串
1 | class LoggingButton extends React.Component { |
另外一个不同的是 React 不支持向事件处理函数 return false,一般 HTML 事件函数中,可以通过 return false 来阻止默认行为,比如
1 | <a href="#" onclick="console.log('The link was clicked.'); return false"> |
Vue 阻止浏览器默认行为的方式最简单,用一个装饰符就可以搞定 <form v-on:submit.prevent="onSubmit"></form>。
而在 React 中,必须调用 preventDefault 方法才能完成以上功能。
1 | function ActionLink() { |
在这里的 e 是 React 封装过后的,因此不用担心游览器差异带来的影响。☺
条件渲染
假设 Greeting 组件根据状态选择渲染 UserGreeting 和 GuestGreeting 中的一个。
1 | function UserGreeting(props) { |
行内条件判断
1 | function Mailbox(props) { |
其它类型的逻辑判断,像三元运算符,if else React 也均支持。
1 | render() { |
1 | render() { |
阻止组件渲染
通过在组件内部 return null 可以达到阻止组件渲染的
1 | function WarningBanner(props) { |
最后
第一章 React 入门 和本章 React 组件都是比较基础的内容,后面会学习全新的程序设计模式 Flux 和 Redux 来管理应用的状态,很多函数式编程的思想正好努力学习一下。