React系列-生命周期<1>

一个人的价值, 在于他贡献了什么, 而不在于他获得了什么。
——爱因斯坦

React生命周期&原生通信

由四张图引发的一系列事件。。。。

image.png

image.png

本文主要根据原生传参展开,顺带温故下生命周期,接下来就是Redux.

第一部分 生命周期

一、概念

在组件创建、加载运行、被销毁的过程中,总是伴随着各种各样的事件,组件在特定时期触发对应的事件,都属于组件的生命周期范畴。

生命周期的三种状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

完整的生命周期如下图所示,可以在代码中,尝试一下,各个方法在什么时候会触发,触发效果是什么。
生命周期.png
图片来源:https://www.cnblogs.com/ygjzs/p/12203390.html

import React from "react";

export default class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: this.props.count
};
}

static defaultProps = {
count: 0
};

increment = () => {
this.setState({
count: this.state.count + 1
});
};

// 在组件即将挂载到页面上的时候执行,此时,组件尚未挂载到页面
componentWillMount() {
console.log("componentWillMount");
}

// 在内存中开始渲染DOM,未展示
render() {
// ⚠️在此如果更新state, 则会进入死循环
return (
<div>
<h1>这是 Counter 计数器组件</h1>
<input type="button" value="加1" onClick={this.increment} />
<hr />
<h3 id="content" ref="h3">
当前的数量是:{this.state.count}
</h3>
</div>
);
}

// 判断组件是否需要更新
shouldComponentUpdate(nextProps, nextState) {
console.log(nextProps, nextState);
return true;
}
// 组件将要更新,但Dom, state还是旧的
componentWillUpdate() {
console.log(
"WillUpdate: " +
document.getElementById("content").innerHTML +
". state: " +
this.state.count
);
}
// 组件完成了更新,此时,state 中的数据、虚拟DOM、页面上的DOM,都是最新的
componentDidUpdate() {
console.log(
"DidUpdate: " +
document.getElementById("content").innerHTML +
". state: " +
this.state.count
);
}
}

第二部分 原生通信

以下示例codesandbox地址https://codesandbox.io/s/gifted-grothendieck-2wsy3
主要实现以下功能:

  • 父子组件通过props互相传值;
  • 孙子组件通过context传参数。

Kapture 2020-03-18 at 16.28.13.gif

一、父子组件互相传值

import React from "react";
import PropTypes from "prop-types";

import Son from "./Son";

export default class Father extends React.Component {
constructor(props) {
super(props);
this.state = {
content: "",
inputMsg: "",
receiveMsg: "",
contextMsg: ""
};
}
/** ------使用props传值----------- */
// 更改状态
inputMsg = item => {
this.setState({
inputMsg: item.target.value
});
};
sendMsg = () => {
const text = this.state.inputMsg;
this.setState({
content: text
});
};

/**
* 父组件将一个函数作为 props 传递给子组件,
* 子组件调用该回调函数,便可以向父组件通信。
*/
handleCallBack = msg => {
this.setState({
receiveMsg: msg
});
};
/** ------使用props传值----------- */


/** ------使用context传值----------- */
// 父组件声明自己支持 context
static childContextTypes = {
callback: PropTypes.func
};

// 父组件提供一个函数,用来返回相应的 context 对象
getChildContext() {
return {
callback: this.callback.bind(this)
};
}

callback(msg) {
this.setState({
contextMsg: msg
});
}
/** ------使用context传值----------- */

render() {
return (
<div>
<h1>父子组件互相传值</h1>
<input value={this.state.inputMsg} onChange={this.inputMsg} />
<button onClick={this.sendMsg}> 传给子组件 </button>
<hr />
<label> 将要发送的数据: {this.state.inputMsg} </label>
<hr />
<label> 接受props方式的数据: {this.state.receiveMsg} </label>
<hr />
<label> 接受Context方式的数据: {this.state.contextMsg} </label>
<hr />

<Son
content={this.state.content}
handleCallBack={this.handleCallBack.bind(this)}
/>
</div>
);
}
}
import React from "react";
import GrandSon from "./GrandSon";

export default class Son extends React.Component {
// 回调父组件的handleCallBack方法,向上传值
callBack = msg => {
return () => {
this.props.handleCallBack(msg);
};
};

render() {
return (
<div>
// 1. 接受父组件传过来的值
<h4>子组件接受的值:{this.props.content}</h4>
// 2. 向父组件传值
<button onClick={this.callBack("发送: " + this.props.content)}>
向父组件传值
</button>
<hr />
<GrandSon />
</div>
);
}
}

二、跨级组件

import React from "react";
import PropTypes from "prop-types";

export default class GrandSon extends React.Component {
// 子组件声明自己需要使用 context
static contextTypes = {
callback: PropTypes.func
};
// 回调函数
cb = msg => {
return () => {
this.context.callback(msg);
};
};
render() {
return (
<div>
<button onClick={this.cb("发消息")}> 孙子向爷爷发消息 。</button>
</div>
);
}
}

总结

官方文档一看就会,一写就蒙圈。。
通过以上这两个示例,主要加深了对React的理解,将组件与数据串联起来,页面很丑,数据来凑,示例中没有数据校验与代码优化。
接下来对剩余的几张图【Redux、Dva】以示例的方式展示出来,应该快轮到antd了。

参考链接

React 生命周期