React基础

  React学习笔记。

#React基础

创建React Dom的几种方式

通过Reat的createElement方法进行创建,通过render函数进行渲染

1
2
3
4
5
6
7
8
9
var h1 = React.createElement(
"h1",
{
className:"test1",
},
“我是内容”
//渲染
ReactDOM.render(h1,document.getElementById('root'));

编写一个JavaScript函数,它接受一个带有数据的“props”(代表属性)对象参数并返回一个React元素。我们将这些组件称为“功能”,因为它们实际上是JavaScript的功能

1
2
3
4
5
function Tseta(props){
return <h2>hahah{props.name}</h2>
}
const ele = <Tseta name="shabi" />
ReactDOM.render(ele,document.getElementById('root'));

ES6的定义方式

1
2
3
4
5
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}

警告:
始终用大写字母开始组件名称。
React将以小写字母开头的组件视为DOM标签。例如,

表示一个HTML div标签,但表示一个组件,并且需要Welcome在范围内。

构成组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);

但是通过这样的实现方式,是无法访问到this对象,并且不会进入到生命周期。

  1. 组件不会被实例化,整体渲染性能得到提升
    因为组件被精简成一个render方法的函数来实现的,由于是无状态组件,所以无状态组件就不会在有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。
  2. 组件不能访问this对象
    无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:thisthis.state等均不能访问。若想访问就不能使用这种形式来创建组件
  3. 组件无法访问生命周期的方法
    因为无状态组件是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。
  4. 无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用

React生命周期及一些钩子

生命周期

生命周期

定义一个TodoList的React组件,通过继承React.Component来实现

1
2
3
4
5
6
class TodoList extends React.Component {
constructor(props){
super(props);
this.state = {};
}
}

getDefaultProps

执行过一次后,被创建的类会有缓存,映射的值会存在this.props,前提是这个prop不是父组件指定的
这个方法在对象被创建之前执行,因此不能在方法内调用this.props ,另外,注意任何getDefaultProps()返回的对象在实例中共享,不是复制

getInitialState

控件加载之前执行,返回值会被用于state的初始化值

componentWillMount

执行一次,在初始化render之前执行,如果在这个方法内调用setState,render()知道state发生变化,并且只执行一次

render

render的时候会调用render()会被调用
调用render()方法时,首先检查this.propsthis.state返回一个子元素,子元素可以是DOM组件或者其他自定义复合控件的虚拟实现
如果不想渲染可以返回null或者false,这种场景下,React渲染一个

note info:
render()方法是很纯净的,这就意味着不要在这个方法里初始化组件的state,每次执行时返回相同的值,不会读写DOM或者与服务器交互,如果必须如服务器交互,在componentDidMount()方法中实现或者其他生命周期的方法中实现,保持render()方法纯净使得服务器更准确,组件更简单

componentDidMount

在初始化render()之后只执行一次,在这个方法内,可以访问任何组件,componentDidMount() 方法中的子组件在父组件之前执行

**从这个函数开始,就可以和 JS 其他框架交互了,

例如设置计时 setTimeout 或者 setInterval,或者发起网络请求


shouldComponetUpdate

这个方法在初始化render()时不会执行,当props或者state发生变化时执行,并且是在render()之前,当新的props或者state不需要更新组件时,返回false

1
2
3
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}

shouldComponentUpdate方法返回false时,讲不会执行render()方法,componentWillUpdatecomponentDidUpdate方法也不会被调用。

note info:
默认情况下,shouldComponentUpdate方法返回true防止state快速变化时的问题,但是如果state不变,props只读,可以直接覆盖shouldComponentUpdate用于比较propsstate的变化,决定UI是否更新,当组件比较多时,使用这个方法能有效提高应用性能

componentDidUpdate

组件更新结束之后执行,在初始化render()时不执行

componentWillRecevieProps

当props发生变化时执行,初始化render时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用

componentWillUnmount

当组件要被从界面上移除的时候,就会调用componentWillUnmount(),在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等


note info:
建议只有在componentWillMount,componentDidMount,componentWillReceiveProps方法中可以修改state值