1.React插槽
import React, { Component } from 'react'
import Child from './compoent/Child'
export default class App extends Component {
render() {
return (
<div>
<Child>
<div>App下的div</div>
</Child>
</div>
)
}
}
import React, { Component } from 'react'
export default class Child extends Component {
render() {
return (
<div>
Child
</div>
)
}
}
可以发现在Child组件内部的 <div>App下的div</div>并没有被渲染出来!!!!
应该使用react插槽:{this.props.children} 固定写法
多个的话,也可以指定第几个
2.React生命周期
2.1初始化阶段 (执行一次)
componentWillMount() :render之前最后一次修改状态的机会
componentDidMount() :成功render并渲染完成真实DOM之后触发,可以修改DOM
render()
执行顺序:componentWillMount--》render--》componentDidMount
import React, { Component } from 'react'
export default class App extends Component {
state={
myname:"www"
}
componentWillMount(){
console.log("componentWillMount()");
this.setState({
myname:"xxx"
})
}
componentDidMount(){
console.log("componentDidMount()");
//数据请求axios
//订阅函数调用
//setInterVal
//基于创建完的dom进行 ....
//....
}
render() {
console.log("render()");
return (
<div>
App---{this.state.myname}
</div>
)
}
}
警告:
componentWillMount官方已经不推荐使用了。componentWillMount已被重命名,不建议使用。
可以将代码移动到componentDidMount,或者在构造函数中设置初始状态。
可以将componentWillMount重命名为UNSAFE_componentWillMount,以在非严格模式下抑制此警告。
初始化案例:
import React, { Component } from 'react'
import BetteScroll from 'better-scroll'
export default class App extends Component {
state = {
list: ["11111", "22222", "33333", "44444", "55555", "66666", "77777"]
}
componentDidMount() {
// 在dom渲染完成后使用
new BetteScroll("#listdiv");
}
render() {
return (
<div id="listdiv" style={{background:'yellow',overflow:'hidden',height:'100px',width:'300px'}}>
<ul>
{this.state.list.map((item) =>
<li key={item}>{item}</li>)}
</ul>
</div>
)
}
}
2.2 运行中阶段 (执行多次)
componentWillUpdate() :执行更新前调用
componentDidUpdate(prevProps,prevState) :执行更新完毕后调用。可以有两个形参 ,分别代表更新前旧的属性,旧的状态。
shouldCompoentUpdate(nextProps,nextState) :执行更新前调用,询问是否需要更新,返回false会阻止render调用。 性能优化函数
render()
componentWillReceiveProps(nextProps) :父组件修改属性时触发。最先获得父组件传来的属性,并可以利用属性进行ajax或者逻辑处理
2.3 销毁阶段
componentWillUnmount :在删除组件之前进行清理操作,比如计时器和时间监听器
{this.state.next==='aaaa' && <Field/>} 这种形式的创建子组件就会存在删除组件
3.老生命周期的问题
(1) componentWillMount ,在ssr中 这个方法将会被多次调用, 所以会重复触发多遍,同时在这里如果绑定事件, 将无法解绑,导致内存泄漏 , 变得不够安全高效逐步废弃。
(2) componentWillReceiveProps 外部组件多次频繁更新传入多次不同的 props,会导致不必要的异步请求
(3) componetWillupdate, 更新前记录 DOM 状态, 可能会做一些处理,与componentDidUpdate相隔时间如果过 长, 会导致 状态不太信
4.新生命周期的替代
(1)getDerivedStateFromProps 第一次的初始化组件以及后续的更新过程中(包括自身状态更新以及父传子) , 返回一个对象作为新的state,返回null则说明不需要在这里更新state。
//老的生命周期的写法
componentDidMount() {
if (this.props.value !== undefined) {
this.setState({
current: this.props.value
})
}
}
componentWillReceiveProps(nextProps){
if (nextProps.value !== undefined) {
this.setState({
current: nextProps.value
})
}
}
// 新的生命周期写法
static getDerivedStateFromProps(nextProps,nextState) {
if (nextProps.value !== undefined) {
return {
current: nextProps.value
}
}
return null
}
4.react中性能优化的方案
1. shouldComponentUpdate
控制组件自身或者子组件是否需要更新,尤其在子组件非常多的情况下, 需要进行优化。
2. PureComponent
这里改为PureComponent
PureComponent会帮你 比较新props 跟 旧的props, 新的state和老的state(值相等,或者 对象含有相同的属性、且属性值相等 ),决定shouldcomponentUpdate 返回true 或者 false, 从而决定要不要呼叫 render function。
注意: 如果你的 state 或 props 『永远都会变』,那 PureComponent 并不会比较快,因为 shallowEqual 也需要花时间。