前言:React 16.8 更新了一些新的生命周期,增加了hooks无状态组件,原有的class类组件的生命周期也进行了更新优化
我认为hooks才是React想做的事,React不想废弃原来的类组件,同时想扶正hooks,做了一些兼容,写法上的区别,但是最终结果是一样的,
下面我们来讨论一下新增加的生命周期:
1、getDerivedStateFromProps(props,state)
- 相当于componentwillmount 和 componentWillReceiveProps合并
- 主要是应用在于封装组件时调用,组件的state取决于props变化,
- 无条件的根据 props来更新内部 state,也就是只要有传入 props值, 就更新 state
- 只有 props 值和 state值不同时才更新 state 值。
我们自己查看会发现这不就是和React.useEffect(()=>{},[]),中的依赖参数同等效果,我们在封装组件时可以用到,具体看代码
类组件:
class List extends React.Component { state = { list: [] } static getDerivedStateFromProps(props, state) { if(props.list !== state.list){ return { list: props.list } } return null; } render() { .... // 展示 list } }
函数组件:
// 函数组件 const List = React.memo((props) =>{ const [list,setList] = React.useState([]); React.useEffect(()=>{ setList(props.list); }, [props.list]); return ( .... // 展示 list )
});
2、getSnapshotBeforeUpdate(prevProps,prevState)
- 替换componentWillUpdate函数,将参数返回并传递给componentDidUpdate周期函数
getSnapshotBeforeUpdate()
在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给componentDidUpdate()
。- 此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。
class ScrollingList extends React.Component { constructor(props) { super(props); this.listRef = React.createRef(); } getSnapshotBeforeUpdate(prevProps, prevState) { // 我们是否在 list 中添加新的 items ? // 捕获滚动位置以便我们稍后调整滚动位置。 if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; } return null; } componentDidUpdate(prevProps, prevState, snapshot) { // 如果我们 snapshot 有值,说明我们刚刚添加了新的 items, // 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。 //(这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; } } render() { return ( <div ref={this.listRef}>{/* ...contents... */}</div> ); } }
继续完善。。。