vanilla
import "./styles.css";
// create div
let div = document.createElement("div");
div.style.border = "1px solid red";
let state = 0;
div.innerHTML = `
<p>${state}</p>
<button>+1</button>
<button>die</button>
`;
let app = document.getElementById("app");
// mount
app.appendChild(div);
div.querySelector("button").onclick = () => {
state += 1;
// update => render
div.querySelector("p").innerText = state;
};
div.querySelectorAll("button")[1].onclick = () => {
div.querySelector("button").onclick = null;
div.querySelectorAll("button")[1].onclick = null;
div.remove(); // unmount
div = null;
};
React
class组件生命周期
constructor
用途:
- 初始化state
- 初始化props
- bind this
shouldComponentUpdate
作用:允许我们手动判断是否要进行组件更新,我们可以根据应用场景灵活地设置返回值,以避免不必要的更新。返回true表示不阻止UI更新,返回false表示阻止UI更新
可以使用React.PureComponent代替React.ComponentshouldComponentUpdate(newProps, newState){
if(newState.n === this.state.n){
return false
} else {
return true
}
}
PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。
render
用途:
展示视图
render(){
if (this.state.n % 2 === 0) {
return <div>偶数</div>
} else {
return <div>奇数</div>
}
}
只能返回一个根元素,如果有2个根元素,可以用
render用array.map写for循环
render(){
return this.state.array.map(n=><div>{n}</div>)
}
componentDidMount
在元素插入页面后执行代码,这些代码依赖DOM
componentDidMount() {
const div = document.getElementById('xxx')
const {width} = div.getBoundingClientRect()
this.setState({width})
}
此处可以发起加载数据的AJAX请求(官方推荐)
首次渲染会执行此钩子
使用ref 防止ID冲突
calss App extends React.Component {
divRef = undefined
constructor(props) {
super(props)
this.state = {
n: 1,
width: undefined
}
this.divRef = React.createRef()
}
render(){
return (
<div ref={this.divRef}>Hello World, {this.state.width}</div>
)
}
componentDidMount(){
const div = this.divRef.current
const {width} = div.getBoundingClientRect()
this.setState({width})
}
}
componentDidUpdate
在视图更新后执行代码
也可以发起AJAX请求,用于更新数据
首次渲染不会执行此钩子
若shouldComponentUpdate返回false,则不触发此钩子
componentWillUnmount
组件将要被移除页面然后销毁时执行代码
unmount过的组件不会再次mount
在unmount里取消监听,取消Timer, 取消AJAX请求,谁污染谁治理
其他钩子
getDerivedStateFromProps
getSnapshotBeforeUpdate
getDerivedStateFromError
componentDidCatch
被废除的钩子
componentWillMount
componentWillReceiveProps
componentWillUpdate
分阶段看钩子执行顺序
- 首次渲染:constructor -> render -> componentDidMount
- 再次渲染:shouldComponentUpdate -> render -> componentDidUpdate
- 销毁: componentWillUnmount
函数组件模拟生命周期
componentDidMount
useEffect(()=>{console.log('第一次渲染')}, [])
componentDidUpdate
useEffect(()=>{console.log('任意属性变更')})
useEffect(()=>{console.log('n变了')}, [n])
componentWillUnmount
useEffect(()=>{
console.log('第一次渲染')
return ()=>{
console.log('组件要死了')
}
})