<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello_react</title>
<!-- 引入react,为了使用 React对象 -->
<script src="js/react.development.js"></script>
<!-- 引入 react-dom, 为了使用 ReactDOM 对象 -->
<script src="js/react-dom.development.js"></script>
<!-- 引入 babel, 为了 解析 JSX -->
<script src="js/babel.min.js"></script>
<!-- 引入prop-types,为了对 props属性的类型、必要性、默认值进行限制,全局多了一个 PropTypes对象 -->
<script src="js/prop-types.js"></script>
</head>
<body>
<div id="test"></div>
<!-- 1.引出生命周期 -->
<!-- <script type="text/babel">
class Life extends React.Component {
state = {
opacity: 1
}
// death是通过onClick事件的回调使用----》所以必须写成赋值语句+箭头函数形式---》目的是让death中的this指向组件实例对象
death = () => {
// 清除定时器
// clearInterval(this.timer)
// 卸载组件
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
// 报错:类里面不能随便写代码。
// 类里面可以写什么:构造器、方法、static、赋值语句
// setInterval(() => {
// }, 200);
// action = () => {
// setInterval(() => {
// let { opacity } = this.state
// opacity -= 0.1
// if( opacity <= 0) opacity = 1
// this.setState({ opacity})
// }, 200);
// }
// 这个函数是通过Lift的实例对象.调用的。
// 什么时候调用?-----组件挂载完毕
componentDidMount() {
this.timer = setInterval(() => {
let { opacity } = this.state
opacity -= 0.1
if( opacity <= 0) opacity = 1
this.setState({ opacity})
}, 200);
}
// 组件将要卸载
componentWillUnmount() {
clearInterval(this.timer)
}
// render调用的时机:初始化渲染、状态更新后
render() {
console.log('render')
// setInterval(() => {
// // 获取原状态
// let { opacity } = this.state
// // 减小0.1
// opacity -= 0.1
// // opacity可能为负数、 在js中: 0.1 + 0.2 !==0.3、 所以if判断条件写成 <=0,而不写 == 0
// if( opacity <= 0) opacity = 1
// // 设置新的透明度
// this.setState({ opacity})
// }, 200);
// 在render中写setState ===》 引发了无限递归 ===》所以定时器写在render中不合适
// 办法:加个“开始变化”按钮,触发定时器
return (
<div>
<h2 style={{opacity: this.state.opacity}}>React 学不会怎么办?</h2>
<button onClick={this.death}>不活了</button>
{/*<button onClick={this.action}>开始变化</button>*/}
</div>
)
}
}
// react一直在一些合适的时间点,干一些合适的事情。
// 生命周期回调函数:你只管写这些函数,react会在合适的时间点帮你自动调用这些函数,所以叫生命周期【回调函数】。因为这些函数是你定义的,但是你没有调用,是react帮你调用的。
// 生命周期回调函数《===》生命周期钩子函数 《===》 生命周期函数 《===》生命周期钩子
ReactDOM.render(<Life/>, document.getElementById('test'))
</script> -->
<!-- 2.生命周期回调函数【旧】 -->
<!-- 生命周期调用顺序与代码书写顺序有关系吗? ----没有关系。 -->
<!-- 挂载时:
===》 constructor ===》 componentWillMount ===》 render ===》 componentDidMount ===》 componentWillUnmount
-->
<!-- 更新时:
===》 setState() 正常更新===》 shouldComponentUpdate 阀门 ===》 componentWillUpdate ===》 render ===》 componentDidUpdate ===》 componentWillUnmount
===》 forceUpdate() 强制更新===》 componentWillUpdate ===》 render ===》 componentDidUpdate ===》 componentWillUnmount
强制更新绕过了阀门。
-->
<!-- <script type="text/babel">
// 创建组件
class Count extends React.Component {
// 【挂载时】构造器---1
constructor(props) {
console.log('Count---constructor')
super(props)
this.state = {count: 0}
}
add = () => {
let {count} = this.state
// 【更新时】 setState()---(1)
this.setState({count: count+1})
}
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
force = () => {
this.forceUpdate()
}
// 【挂载时】组件将要挂载---2
componentWillMount() {
console.log('Count---componentWillMount')
}
// 【挂载时】组件挂载完毕---4
componentDidMount() {
console.log('Count---componentDidMount')
}
// 组件将要卸载 --- 5
componentWillUnmount() {
console.log('Count---componentWillUnmount')
}
// 【更新时】 组件是否更新---(2) 默认返回true、控制组件更新的阀门
shouldComponentUpdate() {
console.log('Count---shouldComponentUpdate')
return true
}
// 【更新时】 组件将要更新---(3)
componentWillUpdate() {
console.log('Count---componentWillUpdate')
}
// 【更新时】 组件更新完毕---(5)
componentDidUpdate() {
console.log('Count---componentDidUpdate')
}
// 【挂载时】挂载---3
// 【更新时】更新---(4)
render() {
console.log('Count---render')
const {count} = this.state
return (
<div>
<h2>当前求和为{count}</h2>
<button onClick={this.add}>点我+1</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不更改状态中的任何数据,强制更新一下</button>
</div>
)
}
}
// 挂载组件
ReactDOM.render(<Count/>,document.getElementById('test'))
</script> -->
<!-- 更新时:
===》 父组件重新render ===》 componentWillReceiveProps===》 shouldComponentUpdate 阀门 ===》 componentWillUpdate ===》 render ===》 componentDidUpdate ===》 componentWillUnmount
-->
<script type="text/babel">
// 创建组件
class A extends React.Component {
state = {
carName: '奔驰'
}
changeCar = () => {
this.setState({carName: '奥托'})
}
render() {
return (
<div>
<div>我是A组件</div>
<button onClick={this.changeCar}>换车</button>
<B carName={this.state.carName}/>
</div>
)
}
}
class B extends React.Component {
// 组件将要接收props---(1)
// 注意:这里有个坑,第一次传的props不算。
componentWillReceiveProps(props) {
console.log('B---componentWillReceiveProps', props)
}
// 【更新时】 组件是否更新---(2) 默认返回true、控制组件更新的阀门
shouldComponentUpdate() {
console.log('B---shouldComponentUpdate')
return true
}
// 【更新时】 组件将要更新---(3)
componentWillUpdate() {
console.log('B---componentWillUpdate')
}
// 【更新时】 组件更新完毕---(5)
componentDidUpdate() {
console.log('B---componentDidUpdate')
}
// 【更新时】更新---(4)
render() {
console.log('B---render')
return (
<div>
我是B 组件,接收到的车是:{this.props.carName}
</div>
)
}
}
// 挂载组件
ReactDOM.render(<A/>,document.getElementById('test'))
</script>
<!-- 3. 总结生命周期
生命周期分为三个阶段:
1. 初始化阶段---由ReactDOM.render触发--初次渲染
constructor---componentWillMount----render----componentDidMount
2. 更新阶段----由组件内部this.setState() 或者 父组件render 触发
shouldComponentUpdate --- componentWillUpdate---render---componentDidUpdate
强制更新 forceUpdate 没有阀门。
3. 卸载组件--由ReactDOM.unmountComponentAtNode() 触发
componentWillUnmount
常用的有: componentDidMount 适用于页面一上来做点什么事情。一般做一些初始化的事情。例如:开启定时器、发送网络请求、订阅消息
componentWillUnmount 收尾的事情:关闭定时器、取消订阅消息
render 必须要用
-->
</body>
</html>