第4章 数据流
- 由于react的数据流向是单向的(其父节点传递到子节点),
- 因此组件是简单且易于把握的(它们只需要从父节点获取props渲染即可)
- 假如顶层组件的某个prop改变了,react会递归地向下遍历整个组件树,重新渲染所有使用这个属性的组件。
- react组件内部还具有自己的状态,这些状态只能在组件内修改。react组件本身很简单,你可以把它们看成是一个函数,它接受props和state作为参数,返回一个虚拟的dom表现。
Props(properties 特性)
用途:可以把任意类型的数据传递给组件
2种方式设置props:
setProps注意点:
可以通过this.prpos访问props,但绝不能通过这种方式修改它。一个组件绝对不可以修改自己的props。
在jsx中,可以把props设置为字符串:
<a href="http://www.molinblog.com">molinblog</a>
也可以使用{}语法来设置,注入JavaScript传递任意类型的变量:
{'http://www.molinblog.com/blog/' + blog.id}>{blog.title}</a>
还可以使用JSX的展开语法把props设置成一个对象:
@H_404_74@render () { var props = { one: 'foo',two: 'bar' }; return ( <SurveyTable {...props} /> ) }props还可以用来添加事件处理程序:
@H_404_74@render () { return ( <a className='button save' onClike={this.handleClick}>Save</a> ); } handleClick: function() { // ... }PropsTypes
- 用途:通过在组件中定义一个配置对象,来验证props的方式
- 在应用中使用PropsTypes并不是强制性的,但这提供了一种极好的方式来描述组件的API
一脸黑线?????????、、
getDefaultProps
- 用途:设置属性的默认值(针对那些非必需属性)
- getDefaultProps不是在组件实例化时被调用,而是在React.createClass调用时就被调用了,返回值被缓存起来。也就是说,不能在getDefaultProps中使用任何特定的实力数据
- 在ES6中为属性:defaultProps(可以标识static定义在class内,也可以定义在class外)
- 在ES5中为方法:getDefaultProps: function(){return {name:value}};
es5中使用示例:
@H_404_74@var NewDom = React.createClass({//类名一定要大写开头 getDefaultProps: function() {//设置默认属性 return {title:'133'}; },propTypes: { title:React.PropTypes.string,},136)">//属性校验器,表示必须是string render: function() { return <div>{this.props.title}</div>;//变量用花括号标识 } });es6中使用示例:
@H_404_74@const React = require('react'); const ReactDOM = require('react-dom'); import {Promise} from 'es6-promise' class NewDom extends Component{ //不能再组件定义的时候定义一个属性 render() { return <div >{this.props.title}</div>; }//开头花括号一定要和小括号隔一个空格,否则识别不出来 } //es6 这两个属性不能写在class内。 NewDom.propTypes={//属性校验器,表示改属性必须是string,否则报错 title: React.PropTypes.string,} NewDom.defaultProps={title:'fsdfd133'};//设置默认属性 ReactDOM.render(( <NewDom></NewDom> ),document.querySelector('#init'))state
- 每个react组件都会有自己的state,state与props的区别在于:state只存在于组件的内部
- state可以用来确定一个元素的视图状态。
- state可以通过setState修改,只要setState被调用,render就会被调用。
- 如果render函数的返回值有变化,虚拟DOM就会更新,真实的DOM也会被更新,最终用户就会在浏览器中看到变化。
- 千万不能直接修改this.state,永远记得要通过this.setState方法修改。
放在state和props的各是哪些部分?
- state中应存那些简单的组件正常工作时的必须要的数据。(布尔值,输入框值等)
- 不要尝试把props复制到state中,要尽可能把props当作数据源
总结
- 使用了props在整个组件树中传递数据和配置
- 避免在组件内部修改this.props或调用this.setProps,请把props当作是只读的
- 使用props来做事件处理器(下一章会细节化),与子组件通信
- 使用state存储简单的视图状态,比如下拉框是否可见这样的状态
- 使用this.setState来设置状态,而不要使用this.state直接修改状态
第5章 事件处理
绑定事件处理器
react处理的事件本质和原生js一样(包括命名)
jsx版:
@H_404_74@<button className="btn btn-save" onClick={this.handleSave}>Save</button>js版
@H_404_74@React.DOM.button({className: "btn btn-save",onClick: this.handleSaveClicked},"Save");jsx的写法类似HTML内联时间处理器属性,比如onClick,但其实在底层实现上并没有使用HTML的onClick属性(而是通过事件处理之类的方法?)。
其中绝大部分事件不需要额外的处理就能工作,但是触控事件需要通过调用以下的代码手动启用:
@H_404_74@React.initializeTouchEvents(true) // 是否已被改动????事件和状态
解决组件随着用户输入而改变的问题,经过特定组件渲染后,绑定的事件处理器方法负责处理行为。
根据状态进行渲染
可以在render中读取this.state,然后根据this.state的值渲染出不同的页面。
更新状态
更新组件状态有两种方案:组件的setState方法和replaceState方法。replaceState用一个全新的state对象完整地替换掉原有的state。使用不可变数据结构来表示时,这种方式很有效,不过很少应用于其他场景下。
⚠️永远不要尝试通过setState或者replaceState以外的方式去修改state对象。类似this.saveInProgress = true通常不是一个好主意,因为它无法通过React是否需要重新渲染组件,而且可能会导致下次调用setState时出现意外结果。
本节可参考极客学院
事件对象
使用event.target.value可以获取表单中input值。
事件处理程序通过 合成事件(SyntheticEvent)的实例传递,SyntheticEvent 是浏览器原生事件跨浏览器的封装。SyntheticEvent 和浏览器原生事件一样有 stopPropagation()、preventDefault() 接口,而且这些接口夸浏览器兼容。
如果出于某些原因想使用浏览器原生事件,可以使用 SyntheticEvent的nativeEvent 属性获取。
本节可参考极客学院
总结
- 在react组件上绑定事件处理器
- 在事件处理器当中更新组件的内部状态。组件状态的更新会出发重绘
- 实现组件的render函数用来渲染this.state的数据
第6章 组件的复合
传统HTML当中,元素是构成页面的基础单元。在React中,React组件是构成页面的基础单元。
本质上,一个组件就是一个JavaScript函数,它接受属性(props)和状态(state)作为参数,并输出渲染好的HTML。组件一般被用来呈现和表达应用的某部分数据,因此你可以把react组件理解为HTML元素的扩展。
扩展HTML
React加jsx是强大而富有表现力的工具,允许我们使用类似HTML的语法创建自定义元素。比起单纯的HTML,它们还能够控制生命周期中的行为。
React偏爱符合,即通过结合小巧的、简单的组件和数据对象,构造大而复杂的组件。React组件使不可以扩展的,而是通过组件之间的组合来构建应用。
组件复合的例子
组合模式的特征:选择题组件有一个单选框,单选框有一个输入框元素Input。
组装HTML
对于每一个非必需的属性都需要一个默认值,可以把它添加到defaultProps中。
追踪状态
组件需要记录随时间而变化的数据。
整合到父组件中
将子组件放到父组件中
父组件、子组件关系
子组件与其福组件通信的最简单方式就是使用属性(props)。父组件可以通过属性传入一个毁掉函数,子组件在需要时进行调用。
组件的复合知识React提供的用于定制和特殊化组件的方式之一。
可通过本章的例子深入了解组件的复合。page44~52
第7章 mixin
mixin允许我们定义可以在多个组件中公共用的方法。
什么是mixin
mixin相当简单,他们就是混合进组件类中的对象而已。React在这方面实现得更加深入,它能防止静默函数覆盖,同时还支持多个mixin混合。
以component开头的生命周期函数,如componentDidMount,会按照在mixin数组中定义的顺序被调用,并最终调用组件中定义的componentDidMount,如果它存在的话。
关于mixin的其它用法可参考:
- 一个监听事件并修改state的mixin(如flux store mixin)。
- 一个上环mixin,它负责处理XHR上传请求,同时将状态以及上传的进度同步到state
- 渲染层mixin,简化在<\/body>之前渲染子元素的过程(如渲染模态对话框)
mixin是解决代码段重复的最强大工具之一,它同时还能让组件保持专注于自身的业务逻辑。mixin允许我们使用强大的抽象功能,甚至有些问题如果没有mixin就无法被优雅地解决。
即使我们只打算在单个组件中使用一个mixin,它还是为我们提供了描述一个特定行为或角色并提供给该组件的能力。mixin减少了我们在了解整个组件之前需要阅读的代码量,同时允许我们在不污染组件本身的情况下做一些丑陋的处理(比如管理内部__interval)。