vanilla
import "./styles.css";// create divlet 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");// mountapp.appendChild(div);div.querySelector("button").onclick = () => {state += 1;// update => renderdiv.querySelector("p").innerText = state;};div.querySelectorAll("button")[1].onclick = () => {div.querySelector("button").onclick = null;div.querySelectorAll("button")[1].onclick = null;div.remove(); // unmountdiv = 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 = undefinedconstructor(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.currentconst {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('组件要死了')}})
