1.React
- React是Facebook在2013年发布于GitHub的JavaScript库。
- 将用户界面抽象成一个个组件,引入JSX语法,简化组件复用。
- 将真实DOM树转换成Virtural DOM,并通过创建和更新virtural element进行管理。
- React由React Core库和React DOM库组成,React Core旨在通过使用JavaScript和JSX以同构的方式构建和共享可组合的UI组件,React DOM拥有用于DOM渲染和服务器端渲染的方法。
2.React优点
- React是声明式风格,视图变更可通过内部状态变更来实现,简洁直观,利用DOM diff比对实际和虚拟DOM,仅更新必要部分。而jQuery需要实际操作DOM,耗性能,Angular由于其双向绑定可能导致事件失控。
- React使用纯JavaScript的Component-Based Architecture(CBA)分离关注点,松散耦合,代码重用。而Angular需要使用带有指令的Domain Specific Language(DSL),存在两种语言。
- React隐藏了底层接口并提供归一化/合成的方法及属性,另还有一组触摸事件的合成事件。
- 在服务器端渲染React元素,便于SEO,提高性能。
3.React缺点
- React需要和Redux/React Router等配合实现和Angular相当的功能。
- React的数据流是单向的。
- React不是开箱即用的响应式库。
4.react生命周期
相关函数:
constructor(props, context):构造函数,在创建组件的时候调用一次。
void componentWillMount():组件挂载之前调用一次,若在这个函数中调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。
void componentDidMount():组件挂载之后调用一次,此时,子组件也都挂载好了,可以使用refs。
void componentWillReceiveProps(nextProps):父组件发生render的时候子组件就会调用,不管props有没有更新,也不管父子组件之间有没有数据交换,props是父组件传递给子组件的。
bool shouldComponentUpdate(nextProps, nextState):组件挂载之后,每次调用setState后都会调用shouldComponentUpdate判断是否需要重新渲染组件。默认返回true,需要重新render。在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。
void componentWillUpdate(nextProps, nextState):shouldComponentUpdate返回true或者调用forceUpdate之后,componentWillUpdate会被调用。
void componentDidUpdate():除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。
ReactElement render():render是一个React组件所必不可少的核心函数(上面的其它函数都不是必须的)。记住,不要在render里面修改state。
void componentWillUnmount():组件被卸载的时候调用。一般在componentDidMount里面注册的事件需要在这里删除。
在react中,触发render的有4条路径,以下假设shouldComponentUpdate都是按照默认返回true的方式。
- 首次渲染Initial Render
- 调用this.setState (并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
- 父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
- 调用this.forceUpdate
5.JSX
可看成编译为原生JavaScript且获得相比JavaScript提供了更好的语法和功能的迷你语言,JSX并不在浏览器中运行,而是作为待编译的源代码。JSX并不是React必需的,而是可选的,JSX需要预处理工具。
6.React中的state和Redux中的state
组件自身维护的state和Redux中的state并不是一个东西,每个组件本身有自己的state,但在Redux中,应用的state全部存在一个单一的树结构中,即应用的所有状态信息都存储在这个包含map和array的数据结构中。一个Redux应用的状态树是不可变的数据结构,一旦你得到了一棵状态树,它就不会在改变了。任何用户行为改变应用状态,你都会获取一棵映射应用改变后新状态的完整状态树。这说明任何连续的状态(改变前后)都被分别存储在独立的两棵树。你通过调用一个函数来从一种状态转入下一个状态。
7.createElement()
第一个参数为要创建的HTML元素,它有两种输入类型,一种是不带尖括号的标准HTML标签名字字符串,例如,“p”,“h1”,另一种是为React组件类对象。第二个参数为HTML元素的属性数据。第三个参数如果是字符串,则表示为所创元素内部的文本内容,如果不是字符串,则表示为所创元素的子元素。
8.setState()
修改组件的state需要通过this.setState()来实现,但是这个函数需要注意:
状态state的更新可能是异步的,this.setState()方法通过一个队列机制实现state更新,当执行this.setState()的时候,会将需要更新的state合并之后放入状态队列,而不是立即更新。例如:this.props和this.state可能是异步更新的,所以不能依赖他们的值计算下一个state。
//该写法可能导致数据不能及时更新
this.setState({
counter: this.state.counter + this.props.increment,
});
//应该传入一个函数,这个函数将接收前一个状态作为第一个参数,应用更新时的props作为第二个参数
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
为拿到更新的state,可以通过this.setState()的回调函数实现:
void setState (
function|object nextState,
[function callback]
)
9.antd表单
Ant Design Form组件提供了一个create方法,使用form.create()(component)处理之后的component 会接收到一个props.form,使用props.form下的一系列方法,便可以很方便的写出具备自动校验功能的表单。
import {Form} from 'antd'
class LoginForm extends React.Component{
...
// DidMount给表单项赋初值,通常用于编辑已有表单
componentDidMount(){
const {tag, form} = this.props;
let formTag = [];
for(let i = 0; i < tag.length; i ++){
formTag = formTag.concat([tag[i].tagLabel, tag[i].tagValue]);
}
form.setFieldsValue({
'formTag': formTag
});
}
...
render(){
const {getFieldDecorator} = this.props.form;
//表单布局
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 4 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 20 },
},
};
...
return(
<Form {...formItemLayout}>
<Form.Item label="物理值">
{getFieldDecorator('dictCode', {
rules: [
{
required: true,
message: '物理名称不能为空',
},
],
})(<Input />)}
</Form.Item>
...
</Form>
);
}
}
export default Form.create()(LoginForm);