脚手架迅速搭建项目
image.pngnpm install -g create-react-app
create-react-app my-app my-app为自己的demo名称
npm i 安装node_modules
新建demo.js 开始今天的练习
js与HTML 的混写 jsx
没有vue中的模板,没有vue写法清晰整洁,但是可塑性强, 可以随心所欲的进行开发,这提供了更多的可能性
虚拟DOM原理
react将jsx中的dom 先合成一个js对象,这个js对象就是虚拟DOM;
Tree-diff 算法中:key可以优化性能
数组['react','vue','angular'] 变为 ['vue','angular'];
假如没有key 它是一一对应,循环遍历更新;
如果有key会经过比较,可以直接更新 删除react
生命周期
在react 声明组件 是通过class和extends两个关键字,从React.Component这个基类中继承过来,React.Component中包含了一系列的方法、生命周期。
class App extends React.Component{
constructor(props){
super(props)
this.state = {
data:[],
}
}
componentDidMount(){
}
render(){
return(
<div>
app
</div>
)
}
}
export default App;
创建期.png生命周期,大体上可以区分为创建期、存在期、销毁期。
-创建期------组件第一次渲染的执行顺序;
-存在期------组件中数据引起变换二次渲染的执行顺序;
-销毁期------组件销毁的执行顺序;
存在期.png
销毁期.png
举例说明
import React,{Component} from 'react';
class App extends Component{
constructor(props){
super(props)
this.state = {
name:'react'
}
}
componentWillMount(){
console.log('app willMount')
}
componentDidMount(){
window.app = this;
console.log('app didMount')
}
componentWillReceiveProps(nextProps,nextState){
console.log('app willUpdate')
}
componentDidUpdate(nextProps,nextState){
console.log('app DidUpdate')
}
render(){
console.log('App render');
return(
<div>
app:
{this.state.name}
<Son1 name={this.state.name + '-son'}></Son1>
</div>
)
}
}
class Son1 extends Component{
componentWillMount(){
console.log('son1 willMount')
}
componentDidMount(){
console.log('son1 didMount')
}
componentWillReceiveProps(nextProps,nextState){
console.log('son1 willUpdate')
}
componentDidUpdate(nextProps,nextState){
console.log('son1 DidUpdate')
}
render(){
console.log('son1 render')
return(
<div>
son1:
{this.props.name}
<GrandSon1 name={this.props.name + '' +'-grand'}></GrandSon1>
</div>
)
}
}
class GrandSon1 extends Component{
componentWillMount(){
console.log('GrandSon1 willMount')
}
componentDidMount(){
console.log('GrandSon1 didMount')
}
componentWillReceiveProps(nextProps,nextState){
console.log('GrandSon1 willUpdate')
}
componentDidUpdate(nextProps,nextState){
console.log('GrandSon1 DidUpdate')
}
render(){
console.log('GrandSon1 render')
return(
<div>
GrandSon1:
{this.props.name}
</div>
)
}
}
export default App;
为了方便浏览 将3个组件写在一起,实际开发中,还是要严格按照组件划分;
这段代码中写了3个组件, 分别是:父组件app----子组件son1----孙组件grandSon1;
1、首次加载时(创建期)
观察打印输出:可以清晰地看到生命周期加载顺序
app willMount
App render
son1 willMount
son1 render
GrandSon1 willMount
GrandSon1 render
GrandSon1 didMount
son1 didMount
app didMount
2、数据发生变化时(存在期)
挂差打印输出:观察生命周期加载顺序
App render
son1 willUpdate
son1 render
GrandSon1 willUpdate
GrandSon1 render
GrandSon1 DidUpdate
son1 DidUpdate
app DidUpdate
3、销毁期
增加一个条件渲染 {this.state.name && <Son1 name={this.state.name + '-son'}></Son1>}
当this.state.name 有意义的时候 渲染 son1;
当this.state.name 无意义的时候 会销毁son1;
class App extends Component{
constructor(props){
super(props)
this.state = {
name:'react'
}
}
componentWillMount(){
console.log('app willMount')
}
componentDidMount(){
window.app = this;
console.log('app didMount')
}
componentWillReceiveProps(nextProps,nextState){
console.log('app willUpdate')
}
componentDidUpdate(nextProps,nextState){
console.log('app DidUpdate')
}
render(){
console.log('App render');
return(
<div>
app :
{this.state.name}
{this.state.name && <Son1 name={this.state.name + '-son'}></Son1>}
</div>
)
}
}
打印结果
App render
son1 willUnmount
GrandSon1 willUnmount
app DidUpdate
例子中通过定义window.app = this;
在控制执行app.setState({name:''}),是的name 无意义,卸载 son1组件;继而卸载son1中的grandSon1组件;
以上,就是当数据变化引起组件 更新时,react 的生命周期。
遇到的问题
React.StrictMode下 在开发环境中render函数会执行两遍
网友评论