# React框架
##梳理笔记: **属性设置`style={ {marginLeft:"10px"}}`** **添加自定义属性需要使用 data- 前缀** **在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中** **在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代** ```js render(){ return( <div> <h1>{i == 1 ? 'True!' : 'False'}</h1> </div> ) } ``` **return()中只能有一个容器标签** **在添加属性时, class 属性需要写成 className. for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。** ```js { this.filterData().map(item => { return ( <li onClick={() => { this.completedTodo(item) }} className={item.completed ? "oncolor" : ""} key={item.id}>{item.text}</li> ) }) } ``` **onClick 等事件,与原生 HTML 不同,on 之后第一个字母是大写的** **如果有元素内嵌,需要多行展示,则需要 return()** ##一. 特点 1. 声明式设计 −React采用声明范式,可以轻松描述应用。 2. 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。 3. 灵活 −React可以与已知的库或框架很好地配合。 4. JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。 5. 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。 6. 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。 ##二. 组件 **注意:始终使用大写字母开始组件名称**(原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。**除此之外还需要注意组件类只能包含一个顶层标签**) React将以小写字母开头的组件视为DOM标签。 例如:<div />表示一个HTML div标签,但<Welcome />表示一个组件 ###创建组件的方式 ```js import React, { Component } from 'react'; class Name extends Component {} render(<Name />, root); ``` **向组件传递参数,使用 this.props 对象**`return <h1>Hello {this.props.name}</h1>;` ##三. 合成事件 **虚拟的事件机制,本质是事件委托** React元素处理事件与处理DOM元素上的事件差异: * React事件使用camelCase命名(小驼峰命名) * 使用JSX,将传递函数作为事件处理函数{},而不是字符串""。 * react阻止默认事件用`e.preventDefault();`,而不能用返回false的方式阻止默认事件 例,字符串形式: ```js <button οnclick="activateLasers()"> Activate Lasers </button> ``` 例,react事件处理形式: ```js <button onClick={activateLasers}> Activate Lasers </button> ``` **箭头函数的使用** ```js <input type="button" value="提交" onClick={(e) => {}} /> ``` ```js x => x * x 上面的箭头函数相当于: function (x) { return x * x; } ``` ##四. State(异步) **React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。** ##### state和props区别 * state可变 * props不可变 ##伍. 组件的通信方式props ```js 将方法以参数的形式传递(filterData={this.filterData()) <Select type={this.state.type} types={this.state.types} onClick={this.selet.bind(this)}/> <Uls filterData={this.filterData()} onClick={this.onli.bind(this)} /> ``` ```js 设定默认值: static defaultProps = { type:"All", types:[], onClick:function(){} } ``` ```js onClick={e => { this.props.onClick(item) }} ``` 同源策略(协议 IP 端口)=> 跨域:针对浏览器端而言 img,link支持跨域,ajax不支持跨域 ```js <input ref={textInput => this.todoEle = textInput} type="text" /> 取到输入框的值: this.todoEle.value ``` ##表单 **1.受控组件** 受控组件就是为某个form表单组件添加value属性;非受控组件就是没有添加value属性的组件; ```js render: function() { return <input type="text" value="Hello!" />; } ``` 存在问题:渲染后的input组件的用户交互,用户输入的任何值将不起作用,input输入框中的值始终为Hello!。这与HTML中input表现不一致. **可以用defaultValue属性** **2.非受控组件** 表现形式上,react中没有添加value属性的表单组件元素就是非受控组件。 `<input type="text" />` 非受控组件在底层实现时是在其内部维护了自己的状态state;这样表现出用户输入任何值都能反应到元素上。 使用情况: * 受控元素,一般用在需要动态设置其初始值的情况;例如某些form表单信息编辑时,input表单元素需要初始显示服务器返回的某个值然后进行编辑。 * 非受控元素, 一般用于无任何动态初始值信息的情况; 例如form表单创建信息时,input表单元素都没有初始值,需要用户输入的情况 ##生命周期 1. 装载 * constructor * componentWillMount(可以使用 setState, 同时不会引起重绘) * render * componentDidMount(可以使用 setState) 2. 运行 * componentWillReceiveProps(可以使用 setState 同时不会引起重绘) * **shouldComponentUpdate通过返回true或false来控制render()的重复渲染** ```js shouldComponentUpdate(nextProps, nextState){ if(nextProps.count != this.props.count){ return true } return false } ``` * componentWillUpdate * render * componentDidUpdate 3. 卸载 * componentWillUnmount ##redux Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 store--仓库,保存数据,操作数据的方法(行为) action--对行为的一种描述 reducer--处理 dispatch--触发具体的action,接收action对象作为参数 1. 使用函数createStore创建store数据点 2. 创建Reducer。它要改变的组件,它获取state和action,生成新的state 3. 用subscribe监听每次修改情况 4. dispatch执行,reducer(currentState,action)处理当前dispatch后的传入的action.type并返回给currentState处理后的state,通过currentListeners.forEach(v=>v())执行监听函数,并最后返回当前 action状态 **应该把要做的修改变成一个普通对象,这个对象被叫做 action,而不是直接修改 state** ##mobx 1. 定义你的状态,让它们成为观察者(observable) 存储状态(Store state)可以是任何的数据结构,随你定义为:对象,数组,类,循环结构,引用都没所谓。但需要记住一点,就是:随着时间的变化,用MobX 去把它们定义成观察者(observable) ```js import {observable} from 'mobx' let appState = observable({ timer: 0 }) ``` 2. 我们不需要让appState去观察什么。你现在就能创建视图(view),每当appState的相关数据发生变化的时候,就会自动更新。MobX会采用最优的方式去更新你的视图。 ```js import {observer} from 'mobx-react'; @observer class TimerView extends React.Component { render() { return (<button onClick={this.onReset.bind(this)}> Seconds passed: {this.props.appState.timer} </button>); } onReset () { //appState.resetTimer会在下一节完成 this.props.appState.resetTimer(); } }; React.render(<TimerView appState={appState} />, document.body); ``` 3. 修改状态 第三节要说的是修改状态。MobX和其他框架不同,它不会要求你去做什么事情,它只是帮助你去做简单的事情 ```js appState.resetTimer = action(function reset() { appState.timer = 0; }); setInterval(action(function tick() { appState.timer += 1; }), 1000); ```