22.2、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.初始化
在组件初始化阶段会执行
- constructor
- static getDerivedStateFromProps()
- componentWillMount() / UNSAFE_componentWillMount()
- render()
- componentDidMount()
2.更新阶段
props或state的改变可能会引起组件的更新,组件重新渲染的过程中会调用
以下方法:
- componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- componentWillUpdate() / UNSAFE_componentWillUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
3.卸载阶段
componentWillUnmount()
4.错误处理
componentDidCatch() 同Vue的错误函数
子级不能捕获自己的错误,只能父级捕获子级的错误 —— 冒泡
参考文献:
https://reactjs.org/docs/react-component.html
https://blog.csdn.net/qq_29311407/article/details/79861522
constructor init
| react | vue |
|---|---|
| componentWillMount | beforeMount |
| componentDidMount | mounted |
| componentWillUpdate | beforeUpdate |
| componentDidUpdate | updated |
| render 渲染 | |
| componentWillUnmount | beforeDistory |
| 没有componentDidlUnmount | distoryed |
| 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>
res:

https://reactjs.org/docs/react-component.html#defaultprops
22.2、react生命周期与react脚手架(二)的更多相关文章
- 【React】学习笔记(二)——组件的生命周期、React脚手架使用
原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...
- 22.1 、react生命周期(一)
在每个react组件中都有以下几个生命周期方法~我们需要在不同阶段进行讨论 组件生命周期概述 1.初始化 在组件初始化阶段会执行 constructor static getDerivedStateF ...
- React生命周期
在react生命周期中,分2段执行,一个挂载的生命周期,一个是组件发生了数据变动,或者事件触发而引发的更新生命周期. 注:react生命周期很重要,对于很多组件场景的应用发挥重要作用,而且不熟悉生命周 ...
- React 生命周期
前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...
- React生命周期浅析
引言 关于React的生命周期API,官网,有着详细说明.但在实际写代码的过程中,这些说明不能解决所有的疑惑. 所以我列举了一些编码中常见用例,供大家参考. 示例代码如下 /* use case 1. ...
- React生命周期详解
React生命周期图解: 一.旧版图解: 二.新版图解: 从图中,我们可以清楚知道React的生命周期分为三个部分: 实例化.存在期和销毁时. 旧版生命周期如果要开启async rendering, ...
- React生命周期简单详细理解
前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...
- react 生命周期钩子里不要写逻辑,否则不生效
react 生命周期钩子里不要写逻辑,否则不生效,要把逻辑写在函数里,然后在钩子里调用函数,否则会出现问题.
- react复习总结(2)--react生命周期和组件通信
这是react项目复习总结第二讲, 第一讲:https://www.cnblogs.com/wuhairui/p/10367620.html 首先我们来学习下react的生命周期(钩子)函数. 什么是 ...
随机推荐
- MSSQL 调用C#程序集 实现C#字符串到字符的转化
10多年前用过MSSQL 调用C#程序集来实现数据的加密和解密,也搞过通过字符偏移实现简单的加密和解密.这次就总结一下吧: C#如下: public class CLRFunctions { /// ...
- exception:Failed to execute 'toDataURL' on 'HTMLCanvasElement' 解决方案
1.情景展示 当使用canvas 将图片转为base64报错信息如下: Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLC ...
- NOIP2010普及组 三国游戏
题目OJ地址 http://codevs.cn/problem/1129/ https://www.luogu.org/problemnew/show/P1199 题目描述 Description 小 ...
- alpine-bash镜像制作
alpine轻量级基于busybox的发行版,特别适合基于docker的base images. 特点: small.simple.secure 官方地址: https://alpinelinux.o ...
- 【大话QT之十二】基于CTK Plugin Framework的插件版本号动态升级
应用需求: 某些场景下我们可能面临这种问题,在执行着的应用程序不能终止的情况下,升级某个功能(或添,或减.或改动).在不採用CTK Plugin Framework插件系统架构的情况下这将是非常困难的 ...
- java独立小程序实现AES加密和解密
一.需求: web项目中配置文件配置的密码是明文的, 现在需要修改成密文, 加密方式采用AES, 于是写了个工具类用于加密和解密. 又因为这个密码是由客户来最终确定, 所以为了部署时方便起见, 写了个 ...
- Android ANR的产生与分析
ANR即Application Not Responding应用无响应,一般在ANR的时候会弹出一个应用无响应对话框.也许有些开发者在使用某些手机开发中不在弹出应用无响应弹出框,特别是国产手机An ...
- 突破这个四个阶段年薪没有50W,还好意思说是搞Java的?
该视频教程总共分为四个阶段来学习.逐步进阶,并且还会不定期更新.我简介一下每一个阶段的视频资源,学习顺序不分先后. 第一阶段 第一阶段主要从 svn/git 版本号控制.Java高并发.JVM虚拟机. ...
- springmvc(二) ssm框架整合的各种配置
ssm:springmvc.spring.mybatis这三个框架的整合,有耐心一步步走. --WH 一.SSM框架整合 1.1.整合思路 从底层整合起,也就是先整合mybatis与spring,然后 ...
- [lvs]lvs的三种模式
回顾了下lvs的三种模式的调度机制 1.lvs的dr模式中的arp的抑制,eth用自己口arp回应. 2.keepalive是否直接操作rs? 不直接操作, 只操作dr(配lvs) 3.tunnel模 ...
