React学习笔记
1、JSX1.1、引用变量使用{var}来引用变量1.2、属性单个引用时使用this.props.propertynames多个引用时使用...this.props1.3、注释使用 {}包裹注意在html中使用class作为属性名在JSX中则使用className对于 自包含的tag如img/ br/ 在html中,/可以省略但是在JSX中不能省略2、状态react状态是组件内部的可变数据存储是 UI与逻辑的核心。2.1 访问状态state对象是组件的属性对象可以通过this引用来访问。不能在render()方法中调用setState会导致死循环2.2 设置初始状态在render()方法中使用状态数据之前必须对其进行初始化。要设置初始状态在构造函数中使用this.state,同时之前调用 super(props)方法2.3 更新状态使用类方法this.setState(data,callback)来改变状态。当此方法被调用时react将data和当前状态合并然后调用render()方法之后react会调用callback.2.4 状态 和属性状态和属性都是类的特性分别用this.state和this.props表示。状态和属性之间最主要的区别之一是前者可变后者不可变状态和属性的另一区别是属性从父组件传递状态在组件内部而非父组件中定义。2.5 无状态组件设计目的只是渲染视图。当不需要状态时可以使用函数替代React组件。在无状态组件中不能拥有状态但可以有两个属性propTypes和defaultProps3、组件生命周期3.1 事件分类挂载仅调用一次componentWillMount()发生在挂载到DOM之前componentDidMount()发生在挂载和渲染之后挂载顺序为constructor-getInitialState-getDefaultProps-componentWillMount-render-componentDidMount更新调用多次componentWillReceiveProps(nextProps)发生在组件即将接收属性时shouldComponentUpdate(nextProps, nextState)通过判断何时需要更新何时不需要更新允许对组件的渲染进行优化compoentWillUpdate(nextProps, nextState)发生在组件将要更新之前componentDidUpdate(prevProps,prevState)发生在组件更新完成之后卸载仅调用一次componentWillUnmount()允许在组件卸载之前解绑所有的事件监听器或者做其他清理操作3.2 组件3.2.1 函数组件和class组件函数组件定义如下function ComponentName(props) { return h1Hello, {props.name} /h1 }class组件定义为class ComponentName extends React.Component { render() { return h1 Hello, {this.props.name}/h1 } }所有React组件都必须像纯函数一样保护它们的props不被更改3.2.2 组件间通信通信关系有父组件向子组件通信通过属性props子组件向父组件通信回调函数;自定义事件机制跨级组件通信跨级父子关系使用context在父组件中定义getChildContext函数在updateContainer时子组件会读取父组件的getChildContext赋值给子组件的context没有嵌套关系的组件通信自定义事件机制EventEmitter3.2.3 高阶组件其实现方式有属性代理通过被包裹的组件来访问props反射继承高阶组件继承被包裹组件3.2.4 组件优化纯函数原则有对于相同的输入总是返回相同的输出过程中不会有副作用没有额外的状态依赖纯Render主要是通过实现shouldComponentUpdate生命周期方法比如react-addons-pure-render-mixin插件。主要方法有为props设置对象或数组为props设置方法并通过事件绑定在元素上设置子组件使用Immutable对象immutable.js3.3 React的数据载体包含state, props,context。state为内部状态或局部状态。props和context用于在组件间传递数据props仅支持逐层传递context能够跨级传递。3.4 refs用于指向组件实例或者DOMinput typetext ref{(ref) this.myTextInput ref} /其中ref赋值为回调函数其参数ref为DOM节点将DOM节点赋值给myTextInputclass App extends Component { componentDidMount() { // myComp 是 Comp 的一个实例因此需要用 findDOMNode 转换为相应的 DOM const myComp this.refs.myComp; const dom findDOMNode(myComp); } render() { return ( div Comp refmyComp / /div ); } }ref指向字符串用时使用refs.name4、事件处理4.1 处理DOM事件通过定义事件处理程序来并在JSX中将它作为元素的属性值对于事件名称属性使用标准的W3C DOM事件名称以驼峰规范命名。以声明函数出现时需要使用bind(this)以便在事件处理程序 中可以引用类(React元素的实例。如果不绑定this会是null值。 在以下几种场景中不应该使用bind(this)将上下文绑定到类的实例上不需要通过this来引用类的实例时使用旧的风格React.createClass()而不是ES6的类风格时使用箭头函数时((){})也可以在类的构造函数中为事件处理程序执行绑定支持的 DOM事件鼠标事件onClick,onContextMenu,onDoubleClick,onDrag, onDragEnd,onDragEnter,onDragExit,onDragLeave,onDrageOver,onDragStart,onDrop,onMouseDown,onMouseEnter,onMouseLeave, onMouseMove,onMouseOut,onMouseOver,onMouseUp键盘事件onKeyDown,onKeyPress,onKeyUp剪贴板事件onCopy,onCut,onPaste表单事件onChange,onInput,onSubmit焦点事件onFocus,onBlur触摸事件onTouchCancel,onTouchEnd, onTouchMove, onTouchStartUI事件onScroll滚轮事件onWheel选择事件onSelect图片事件onLoad, onError动画事件onAnimationStart, onAnimationEnd, onAnimationIteration过渡事件onTransitionEnd4.2 合成事件的实现方式事件委派自动绑定bind方法构造器内声明箭头函数5、表单表单属性typebutton没有默认行为的按钮上面显示value属性的值默认为空checkbox复选框可设为选中或未选中color用于指定颜色的控件在支持的浏览器中激活时会打开取色器date输入日期的控件年、月、日不包括时间。在支持的浏览器激活时打开日期选择器或年月日的数字滚轮datetime-local输入日期和时间的控件不包括时区。在支持的浏览器激活时打开日期选择器或年月日的数字滚轮email编辑邮箱地址的区域。file让用户选择文件的控件使用accept属性规定控件能选择的文件类型hidden不显示的控件其值仍会提交到服务器。image带图像的submit按钮。显示的图像由src属性规定month输入年和月的控件没有时区number用于输入数字的控件。如果支持的话会显示滚动按钮并提供缺省验证。password单行的文本区域其值会被遮盖。radio单选按钮允许在多个拥有相同name值的选项中其中一个range此控件用于输入不需要精确的数字。控件是一个范围组件默认值为正中间的值同时使用htmlattrdefmin和htmlattrdefmax来规定值的范围reset此按钮将表单的所有内容重置为默认值不推荐。search用于搜索字符串的单行文字区域。submit用于提交表单的按钮tel用于输入 电话号码的控件。text默认值。单行的文本区域输入中的换行会被自动去除time用于输入时间的控件不包括时区。url用于输入url的控件。week用于输入 以年和周数组成的日期不带时区。分为两类受控组件属性有value非受控组件属性有defaultValue,defautChecked等5.1 CSS样式设置可以通过两种方式className属性style属性css模块化方式有Inline Style其与原生CSS不兼容与React相关的有Radium, jsxstyle和react-styleCSS Modules兼容原生CSS使用js来管理样式依赖webpack中的css-loader支持6、扩展6.1 默认属性defaultProps静态属性。如果属性丢失则会呈现默认值。设置默认属性值总是对的因为这样做使得组件的容错性提高。6.2 属性类型和验证通过propTypes静态属性来实现。属性类型的这一功能不会强制改变属性值的数据类型而是提供警告。也就是说如果处于开发者模式并且属性类型不匹配则会在控制台和产品中收到警告消息不用做任何处理来防止使用错误的类型。所有类型都在PropTypes对象中react的属性类型有PropTypes.stringPropTypes.numberPropTypes.boolPropTypes.objectPropTypes.arrayPropTypes.funcPropTypes.any.isRequiredPropTypes.objectOf(PropTypes.number)PropTypes.arrayOf(PropTypes.number)PropTypes.nodePropTypes.instanceOf(Message)PropTypes.elementPropTypes.oneOfType([PropTypes.numbere, ...])定义自定义验证需要做的是创建一条返回Error实体的语句然后在propTypes:{}中使用该语句作为属性的值。6.3 渲染子组件使用children属性{this.props.children}这种简单方式可以渲染所有的子组件。如果有多个子元素它可以是一个数组可以访问以下各个元素{this.props.children[0]},{this.props.children[1]}当只有一个元素时this.props.children不是数组。如果使用this.props.length并且唯一的子元素不是字符串将会导致bug产生。因为length是一个有效的字符口中属性。使用React.Children.count(this.props.children)获取子组件的准确计数。还有其它辅助方法React.Children.map()React.Children.forEach()React.Children.toArray()6.4 高阶组件(High-Order Component)使用displayName区分父组件与子组件默认情况下JSX使用类名作为实例的名称。当需要修改此名称时有名为displayName的静态属性可用。使用扩展运算符传递所有属性。扩展运算符为(...)高阶组件实现方式代理方式操纵props,访问ref, 抽取状态包装组件 继承方式操纵props,操纵生命周期函数,以函数作为子组件6.5 展示组件和容器组件展示组件通常只添加DOM和样式它们有属性但是往往没有状态大多数情况下可以使用无状态组件的功能 。展示组件通常使用this.props.children作为包装器来创建子组件。容器组件通常由HOC生成以注入数据源它们有状态。展示组件和容器组件都可以包含其他展示组件或容器组件但在实践中通常会使展示组件仅包含其他展示组件使容器组件包含其他容器组件或展示组件。7、Flux8、Redux单向数据流基础上有三个基本原则唯一数据源保持状态只读数据改变只能通过纯函数完成8.1 异步redux异步action构造函数的模式是在函数体内返回一个新的函数这个新的函数可以有两个参数dispatch和getState分别代表redux唯一的store上的成员函数dispatch和getState。可以使用中间件redux-thunk,redux-saga,redux-effects,redux-side-effects,redux-loop, redux-observable9、单元测试9.1 分类从人工操作还是写代码来操作的角度分为手工测试和自动化测试从是否需要考虑系统的内部设计角度 分为白盒测试和黑盒测试从测试对象的级别分为单元测试、集成测试和端到端测试从测试验证的系统特性分为功能测试、性能测试和压力测试。9.2 单元测试框架Mocha ChaiJestJest会自动 在当前目录 下寻找满足下列任一条件的Javascript文件作为单元测试代码来执行文件名以.test.js为后缀的代码文件存于__test__目录下的代码文件一种方式是在项目的根目录下创建一个名为test的目录和存放功能代码的src目录并列在test目录下建立和src对应子目录结构每个单元测试文件都以.test.js后缀就能够被Jest找到。这种方法是可以保持功能代码src目录的整洁缺点就是单元测试中引用功能代码的路径会比较长。另一种存放单元测试代码的策略是在每一个目录下创建__test__子目录用于存放对应这个目录的单元测试。这种方法因为功能代码和测试代码放在一起容易比对缺点就是散布在各个目录下的__test__看起来不是很整洁。9.3 单元测试代码组织单元测试代码的最小单位是测试用例。在Jest框架下每个测试用例用一个it函数代表it函数的第一个参数是一个字符串代表的就是测试脸名称 第二个参数是一个函数包含的就是实际的测试用例过程。测试套件由测试用例和其他测试套件构成测试套件可以嵌套使用测试套件和测试用例形成了下树形的组织结构 。describe函数包含与it函数一样的参数两者主要的区别就是describe可以包含it或者另一个descibe函数调用 。describe中有如下函数可以帮助重用代码beforeAll在开始测试套件开始之前执行一次afterAll在结束测试套件中所有测试用例之后执行一次。beforeEach,每个测试用例 在执行之前都执行一次。afterEach,每个测试用例在执行之后都执行一次。参考资料《快速上手React编程》《深入浅出react和redux》《React学习手册》React 官方中文文档 – 用于构建用户界面的 JavaScript 库