22.2、react生命周期与react脚手架(二)

react

一.类:es6

<script type="text/babel">

class Person{

age = 10;

constructor(name){

this.name = name;

//this.age = 10;

}

getName(){

return this.name;

}

getAge(){

return this.age;

}

}

let p = new Person("aaa");

console.log(p.getName());

console.log(p.getAge());

</script>

res:

二.生命周期函数

组件生命周期概述

1.初始化

在组件初始化阶段会执行

  1. constructor
  2. static getDerivedStateFromProps()
  3. componentWillMount() / UNSAFE_componentWillMount()
  4. render()
  5. componentDidMount()

2.更新阶段

props或state的改变可能会引起组件的更新,组件重新渲染的过程中会调用

以下方法:

  1. componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
  2. static getDerivedStateFromProps()
  3. shouldComponentUpdate()
  4. componentWillUpdate() / UNSAFE_componentWillUpdate()
  5. render()
  6. getSnapshotBeforeUpdate()
  7. componentDidUpdate()

3.卸载阶段

componentWillUnmount()

4.错误处理

componentDidCatch() 同Vue的错误函数

子级不能捕获自己的错误,只能父级捕获子级的错误 —— 冒泡

参考文献:

https://reactjs.org/docs/react-component.html

https://blog.csdn.net/qq_29311407/article/details/79861522

constructor init

reactvue
componentWillMountbeforeMount
componentDidMountmounted
componentWillUpdatebeforeUpdate
componentDidUpdateupdated
render 渲染
componentWillUnmountbeforeDistory
没有componentDidlUnmountdistoryed
componentWillReceiveProps(props,state)组件属性更新 —— 状态不会监听
UNSAFE_componentWillReceiveProps(nextProps)
shouldComponentUpdate(nextProps, nextState) 组件属性和状态更新

react                            vue

componentWillMount = beforeMount

componentDidMount = mounted

componentWillUpdate = beforeUpdate

componentDidUpdate = updated

render 渲染

componentWillUnmount = beforeDistory

没有componentDidlUnmount = distoryed

componentWillReceiveProps(props,state) 组件属性更新 —— 状态不会监听

UNSAFE_componentWillReceiveProps(nextProps)

shouldComponentUpdate(nextProps, nextState) 组件属性和状态更新


顺序:

1.初始化

1、constructor

2、componentWillMount(即将被淘汰的方法)、UNSAFE_componentWillMount

(顺序:先执行componentWillMount再执行UNSAFE_componentWillMount)

3、render

4、componentDidMount

5、ReactDom.render(1,2,fn);

2.更新的顺序:

属性更新、状态更新

1.1 componentWillReceiveProps 属性

1.2 shouldComponentUpdate 状态

—————— 特别: 有返回值 true/false

           true继续往下执行

           false终止渲染

2、componentWillMount

3、render

4、componentDidMount

componentWillUpdate 消失 ==>替患者 UNSAFE_componentWillUpdate

3.销毁:释放资源   比如定时器 对象置空null

componentWillUnmount

1、通过原生删除节点的方式不会触发钩子函数

2、必须用过react自身的方式进行释放

ReactDOM.unmountComponentAtNode(container)

切换组件

案例:

exp1:

<script type="text/babel">

class Test extends React.Component{

constructor(...args){

super(...args);

this.state = {a:12,b:5};

//初始化 属性 和数据 内部的属性和函数 只会调用一次

console.log("init constructor",this.state,this.props);

}

componentWillMount(){

//原生dom 渲染之前 做数据交换

console.log("componentWillMount",this.state,this.props);

}

componentDidMount(){

//挂载中 写入页面的dom

console.log("componentDidMount");

}

render(){

//正在渲染页面数据—— 虚拟dom

console.log("render");

return <div>

生命周期

</div>

}

}

ReactDOM.render(

<Test name="aaa"/>,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:

exp2:

1.

<script type="text/babel">

class Test extends React.Component{

constructor(...args){

super(...args);

}

componentWillUnmount(){

console.log("componentWillUnmount");

}

distory(){

let oApp = document.getElementById("app");

//document.body.removeChild(oApp);

ReactDOM.unmountComponentAtNode(oApp);

}

render(){

//正在渲染页面数据—— 虚拟dom

console.log("render");

return <div>

生命周期<input onClick={this.distory.bind(this)} type="button" value="销毁" />

</div>

}

}

ReactDOM.render(

<Test/>,

document.getElementById("app")

);

</script>

res:

<script type="text/babel">

class CompA extends React.Component{

constructor(...args){

super(...args);

}

componentWillUnmount(){

console.log("CompA------componentWillUnmount");

}

render(){

return <div>组件A </div>

}

}

class CompB extends React.Component{

constructor(...args){

super(...args);

}

componentWillUnmount(){

console.log("CompB------componentWillUnmount");

}

render(){

return <div>组件B </div>

}

}

let i = 0;

document.onclick = function(){

i++;

ReactDOM.render(

i%2==0?<CompA/>:<CompB/>,

document.getElementById("app")

);

};

</script>

res:

exp3:

<script type="text/babel">

class Clock extends React.Component{

timer = null;

state = {a:12,iH:"00",iM:"00",iS:"00"};

componentDidMount(){

this.tick();

this.timer = setInterval(()=>{

this.tick();

},1000);

}

componentWillUpdate(){

console.log("componentWillUpdate即将更新");

}

componentDidUpdate(){

console.log("componentDidUpdate更新完成");

}

componentWillUnmount(){

clearInterval(this.timer);

}

tick(){

let oDate = new Date();

this.setState({

iH:this.addZero(oDate.getHours()),

iM:this.addZero(oDate.getMinutes()),

iS:this.addZero(oDate.getSeconds()),

});

}

addZero(n){

return n < 10?`0${n}`:`${n}`;

}

render(){

console.log("render...正在渲染");

return <div>

<span>{this.state.iH}</span>:

<span>{this.state.iM}</span>:

<span>{this.state.iS}</span>

<hr />

<span>{this.state.a}</span>

</div>

}

}

ReactDOM.render(

<Clock/>,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:

exp4:

<script type="text/babel">

class Parent extends React.Component{

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

render(){

return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>

<Child name={this.state.name}/>

</div>

}

}

class Child extends React.Component{

componentWillUpdate(){

console.log("2.componentWillUpdate即将更新");

}

componentDidUpdate(){

console.log("4.componentDidUpdate更新完成");

}

componentWillReceiveProps(){

console.log("1.1.componentWillReceiveProps组件属性更新");

}

shouldComponentUpdate(){

console.log("1.2.shouldComponentUpdate组件属性和状态更新");

return true;

}

render(){

console.log("3.render...正在渲染");

return <div>子组件——{this.props.name}</div>

}

}

ReactDOM.render(

<Parent />,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:

<script type="text/babel">

class Test extends React.Component{

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

componentWillUpdate(){

console.log("2.componentWillUpdate即将更新");

}

componentDidUpdate(){

console.log("4.componentDidUpdate更新完成");

}

componentWillReceiveProps(){

console.log("1.componentWillReceiveProps组件属性更新");

}

render(){

console.log("3.render...正在渲染");

return <div>{this.state.name}<input onClick={this.fn.bind(this)} type="button" value={"按钮"}/></div>

}

}

ReactDOM.render(

<Test />,

document.getElementById("app")

);

</script>

res:

<script type="text/babel">

class Test extends React.Component{

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

componentWillUpdate(){

console.log("2.componentWillUpdate即将更新");

}

componentDidUpdate(){

console.log("4.componentDidUpdate更新完成");

}

shouldComponentUpdate(){

console.log("1.shouldComponentUpdate组件属性和状态更新");

return false;

}

render(){

console.log("3.render...正在渲染");

return <div>{this.state.name}<input onClick={this.fn.bind(this)} type="button" value={"按钮"}/></div>

}

}

ReactDOM.render(

<Test />,

document.getElementById("app")

);

</script>

res:

<script type="text/babel">

class Parent extends React.Component{

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

render(){

return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>

<Child name={this.state.name}/>

</div>

}

}

class Child extends React.Component{

state = {a:1,b:2};

componentWillReceiveProps(props,state){

console.log("1.1.componentWillReceiveProps组件属性更新",props,state);

//在这个方法中调用setState()不会起作用,是由于他在render()前被调用

this.setState({

a:Math.random(),

b:Math.random()

});

}

UNSAFE_componentWillReceiveProps(props,state){

console.log("1.1.UNSAFE_componentWillReceiveProps组件属性更新",props,state);

//在这个方法中调用setState()不会起作用,是由于他在render()前被调用

this.setState({

a:Math.random(),

b:Math.random()

});

}

shouldComponentUpdate(props,state){

console.log("1.2.shouldComponentUpdate组件属性和状态更新",props,state);

return true;

}

render(){

return <div>子组件——{this.props.name}</div>

}

}

ReactDOM.render(

<Parent />,

document.getElementById("app")

);

</script>

res:

exp5:

<script type="text/babel">

class Parent extends React.Component{

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

render(){

return <div>父组件 ----{this.state.name}<input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>

<Child name={this.state.name}/>

</div>

}

}

class Child extends React.Component{

state = {

name:this.props.name

};

static getDerivedStateFromProps(nextProps, prevState){

console.log("1getDerivedStateFromProps",nextProps, prevState);

return true;

}

componentWillReceiveProps(){

console.log("2componentWillReceiveProps");

}

render(){

console.log("3.render...正在渲染");

return <div>子组件——{this.props.name}——{this.state.name}</div>

}

}

ReactDOM.render(

<Parent />,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:

exp6:

<script type="text/babel">

class Test extends React.Component{

constructor(...args){

super(...args);

this.state = {a:12,b:5};

//初始化 属性 和数据 内部的属性和函数 只会调用一次

console.log("init constructor",this.state,this.props);

}

UNSAFE_componentWillMount(){

//原生dom 渲染之前 做数据交换

console.log("UNSAFE_componentWillMount",this.state,this.props);

}

componentWillMount(){

//原生dom 渲染之前 做数据交换

console.log("componentWillMount",this.state,this.props);

}

componentDidMount(){

//挂载中 写入页面的dom

console.log("componentDidMount");

}

render(){

//正在渲染页面数据—— 虚拟dom

console.log("render");

return <div>

生命周期

</div>

}

}

ReactDOM.render(

<Test name="aaa"/>,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:

exp7:

<script type="text/babel">

class Parent extends React.Component{

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

render(){

return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>

<Child name={this.state.name}/>

</div>

}

}

class Child extends React.Component{

//UNSAFE_componentWillReceiveProps用来替代componentWillReceiveProps

componentWillReceiveProps(){

console.log("1.1.componentWillReceiveProps组件属性更新");

}

UNSAFE_componentWillReceiveProps(){

console.log("1.2.UNSAFE_componentWillReceiveProps组件属性和状态更新");

}

render(){

console.log("3.render...正在渲染");

return <div>子组件——{this.props.name}</div>

}

}

ReactDOM.render(

<Parent />,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:

exp8:

<script type="text/babel">

class Parent extends React.Component{

//throw new Error("parent");

state = {

name:Math.random()

}

fn(){

this.setState({

name:Math.random()

});

}

componentDidCatch(){

console.log("Parent ----- componentDidCatch");

}

render(){

return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>

<Child name={this.state.name}/>

</div>

}

}

class Child extends React.Component{

//throw new Error("child");

componentDidCatch(){

console.log("child ----- componentDidCatch");

}

render(){

throw new Error("child");

console.log("3.render...正在渲染");

return <div>子组件——{this.props.name}</div>

}

}

ReactDOM.render(

<Parent />,

document.getElementById("app"),

function(){

console.log("最终渲染完成了");//只会调用一次

}

);

</script>

res:


创建reactapp

方法一、  npx create-react-app myreact

方法二、 1. cnpm i -g create-react-app

     2. create-react-app myreact

cd myreact

npm start


vue-cli:

1、vue-cli2.x vue init webpack myvue

2、vue-cli3.x vue create myvue —— vue.config.js

入口文件:main.js

静态文件:vue-cli2.x   static/

       vue-cli3.x   public/

组件:  .vue   template/script/style

react:

  cnpm i -g create-react-app

  create-react-app myreact

入口文件:index.js

静态文件:public/

组件: .js .css

import "./xxx.css"


react 安装:react, react-dom, and react-scripts —— 后台

webpack/babel...

%PUBLIC_URL%/---> public/


改端口

两种方法:

1、myreact\node_modules\react-scripts\scripts\start.js

2、工程文件 package.json

"start": "set port=8888 && react-scripts start",


要新建两个目录:

1、components

2、assets

    静态文件—— 文件会打包


路由: cnpm i -S react-router-dom

https://reacttraining.com/ 官网 http://reacttraining.cn/

http://react-china.org/t/react-router4/15843

http://react-guide.github.io/react-router-cn/docs/API.html

http://react-guide.github.io/react-router-cn/


jsonp:

http://api.douban.com/v2/movie/in_theaters?callback=xxx&city=北京

subjects

jQuery的ajax没有跨域功能 集成jsonp

exp1:

<script type="text/babel">

class MoveBox extends React.Component{

state = {

id:1,

city:"北京"

}

/*//第二种

shouldComponentUpdate(nextProps, nextState){

console.log(2222,this.state, nextState);

return true;

}**/

fn(data){

//第三种

console.log("fn",this.state, data);

if(this.state.city == data.city)return;

this.setState({

id : data.id,

city:data.city

});

}

render(){

return <div>

{

this.props.arr.map(item=><input

className={this.state.id==item.id?"active":""}

key={item.id}

type="button"

onClick={this.fn.bind(this,item)}

value={item.city}/>)

}

<BoxList city={this.state.city}/>

</div>

}

}

class BoxList extends React.Component{

state = {

movies:[]

};

componentDidMount(){

this.getMovies();

}

/*

shouldComponentUpdate(nextProps, nextState){

console.log(111,nextProps, nextState);

return true;

}*/

UNSAFE_componentWillReceiveProps(props){

/*方法1

console.log(props,this.props);

if(props.city == this.props.city)return;

*/

this.getMovies();

}

getMovies(){

$.ajax({

url:"http://api.douban.com/v2/movie/in_theaters",

data:{

city:this.props.city

},

dataType:"jsonp",

success:(res)=>{

console.log(res);

this.setState({

movies:res.subjects

});

}

});

}

render(){

return <ul>

{

this.state.movies.map(item=><li key={item.id}>{item.title}</li>)

}

</ul>

}

}

let arr = [

{id:1,city:"北京"},

{id:2,city:"上海"},

{id:3,city:"深圳"},

{id:4,city:"青岛"}

];

ReactDOM.render(

<MoveBox arr={arr} />,

$("#app")[0]

);

</script>

exp2:

<script type="text/babel">

class MoveBox extends React.Component{

state = {...this.props.arr[0]};

fn(data){

console.log(this);

//第三种

//console.log("fn",this.state, data);

if(this.state.city == data.city)return;

this.setState({

id : data.id,

city:data.city

});

}

render(){//

return <div>

{/*

this.props.arr.map(item=><input

className={this.state.id==item.id?"active":""}

key={item.id}

type="button"

onClick={this.fn.bind(this,item)}

value={item.city}/>)

}

*/}

<BoxTitle arr={this.props.arr} parent={this} fn={this.fn} />

<BoxList city={this.state.city}/>

</div>

}

}

class BoxTitle extends React.Component{

state = {...this.props.arr[0]}

render(){

return <div>

{

this.props.arr.map(item=><input

className={this.state.id==item.id?"active":""}

key={item.id}

type="button"

onClick={this.props.fn.bind(this.props.parent,item)}

value={item.city}/>)

}

</div>

}

}

class BoxList extends React.Component{

state = {

movies:[]

};

componentDidMount(){

this.getMovies();

}

UNSAFE_componentWillReceiveProps(props){

this.getMovies();

}

getMovies(){

$.ajax({

url:"http://api.douban.com/v2/movie/in_theaters",

data:{

city:this.props.city

},

dataType:"jsonp",

success:(res)=>{

console.log(res);

this.setState({

movies:res.subjects

});

}

});

}

render(){

return <ul>

{

this.state.movies.map(item=><li key={item.id}>{item.title}</li>)

}

</ul>

}

}

let arr = [

{id:1,city:"北京"},

{id:2,city:"上海"},

{id:3,city:"深圳"},

{id:4,city:"青岛"}

];

ReactDOM.render(

<MoveBox arr={arr} />,

$("#app")[0]

);

</script>

https://reactjs.org/docs/react-component.html#defaultprops

以上是 22.2、react生命周期与react脚手架(二) 的全部内容, 来源链接: utcz.com/z/383587.html

回到顶部