ajax mysql项目 react_React16时代,该用什么姿势写 React ?
更新概覽
從 React v16.0 ~ React v16.6 的更新概覽(只涉及部分常用api):
- React v16.0
- render 支持返回數組和字符串
- 支持自定義 DOM 屬性
- 減少文件體積
- React v16.3
- createContext
- createRef、
- 生命周期函數的更新
- React v16.4
更新 getDerivedStateFromProps
- React v16.6
- memo
- lazy
- Suspense
- static contextType
- static getDerivedStateFromError()
- React v16.7(~Q1 2019)
Hooks
接下來將針對影響較大,使用頻率較高的更新點逐一講解。
純函數的PureComponent
我們知道,對 React 組件的性能優化,shouldComponentUpdate函數是很重要的一啪,所以 React 才會在 React.Component的基礎上增加了React.PureComponent,但是對于非class類的純函數寫法,卻沒法增加這樣的便捷處理。 對于這個問題,React16.6 增加了React.memo這個高階組件
一般使用方式:
const C = React.memo(props => {// xxx })React.memo的實現類似React.PureComponent,所以它內部是對對象進行淺比較。 React.memo允許你自定義比較方法,如下:
// 函數的返回值為 true 時則更新組件,反之則不更新 const equalMethod = (prevProps, nextProps): boolean => {// 定義你的比較邏輯 } const C = React.memo(props => {// xxx }, equalMethod)新的生命周期函數是怎樣的
React生命周期分為三個階段:掛載、更新、卸載,React16后又多了一個異常,我們一一看下。
掛載
生命周期的執行順序
render和componentDidMount較 React16 之前無變化。對于掛載過程,我們著重看下constructor、componentWillMount和static getDerivedStateFromProps。
constructor
注意:應避免使用props給state賦值,這樣的話, state 的初始化可以提到constructor外面處理
但是,以上兩件事放到constructor外面處理會更簡單些,如下:
class C extends React.Component {state = {x: 1}handleClick = (e) => {// xxx} }所以,React16 以后用到constructor的場景會變少。
componentWillMount
可以看到,componentWillMount在 react16 中被“刪掉”了(這樣說其實是有問題的,因為 react 并未真正刪除該生命周期函數,只是告誡開發者,該函數在未來版本中會被廢棄掉),那么問題就出現了,原先在這個生命周期中的做的事情,現在該放到哪里去做呢?
首先問自己一個問題,原先的時候都在這個生命周期里做什么?答案是大部分時候會在這里做AJAX請求,然后執行 setState 重新渲染。
然而在componentWillMount里做AJAX請求實在不是一個明智之舉,因為對于同構項目中,componentWillMount是會被調用的。
還有人會在這里面初始化 state ,關于 state 的初始化,請參看樓上小節。
綜上所述,componentWillMount其實本來沒有什么主要作用,如果你的代碼規范,去掉的話,不會對現在的項目產生什么影響。
static getDerivedStateFromProps
上面我們講到,應避免使用props給state賦值,但是在 React16 前我們都是這么做的,現在如果不讓這么操作了,那該在哪里處理這塊邏輯呢? React16 給出的答案就是 static getDerivedStateFromProps ,掛載組件時,該靜態方法會在render前執行。
class C extends React.Component {state = {y: 0}static getDerivedStateFromProps(props, state): State {if(props.y !== state.y) {return {y: props.y};}} }getDerivedStateFromProps的返回值將作為setState的參數,如果返回null,則不更新state,不能返回object 或 null 以外的值,否則會警告。
getDerivedStateFromProps是一個靜態方法,是拿不到實例this的,所以開發者應該將該函數設計成純函數。
這樣,有沒有發現componentWillReceiveProps也就沒有用武之地了?是的,React16 把它也“刪掉”了(這樣說其實是有問題的,因為 react 并未真正刪除該生命周期函數,只是告誡開發者,該函數在未來版本中會被廢棄掉,建議使用更好的getSnapshotBeforeUpdate 或 getDerivedStateFromProps)
更新
生命周期函數的執行順序
static getDerivedStateFromProps前面已經介紹過了,而其他的幾個生命周期函數與 React16 之前基本無異,所以這里主要介紹下getSnapshotBeforeUpdate。
getSnapshotBeforeUpdate
在 react 更新 dom 之前調用,此時 state 已更新; 返回值作為 componentDidUpdate 的第3個參數; 一般用于獲取 render 之前的 dom 數據
- 語法
getSnapshotBeforeUpdate 的使用場景一般是獲取組建更新之前的滾動條位置。
卸載
componentWillUnmount
較之前無變化
異常
componentDidCatch 這個函數是 React16 新增的,用于捕獲組件樹的異常,如果render()函數拋出錯誤,則會觸發該函數。可以按照 try catch 來理解和使用,在可能出現錯誤的地方,使用封裝好的包含 componentDidCatch 生命周期的組建包裹可能出錯的組件。
class PotentialError extends React.Component {state = {error: false,}componentDidCatch(error, info) {console.error(info);this.setState({error});}render() {if (this.state.error) {return <h1>出錯了,請打卡控制臺查看詳細錯誤!</h1>;}return this.props.children; } }如:
const Demo = () => (<PotentialError><div>{{a: 1}}</div></PotentialError> )這樣,Demo 組件即使直接使用對象作為子組件也不會報錯了,因為被 PotentialError 接收了。
新生命周期的完整demo
看看穿上新生命周期這身新衣服后的樣子吧
import React from 'react'export default class MyComponent extends React.Component {constructor(props) {super(props);// 初始化state方式(1)this.state = {}}static defaultProps = {}// 初始化state方式(2)state = {}static getDerivedStateFromProps(props, state) {return state}componentDidCatch(error, info) {}render() {}componentDidMount() {}shouldComponentUpdate(nextProps, nextState) {}getSnapshotBeforeUpdate(prevProps, prevState) {}componentDidUpdate(prevProps, prevState, snapshot) {}componentWillUnmount() {}}Suspense
Hooks
time slicing
【未完待續】
總結
以上是生活随笔為你收集整理的ajax mysql项目 react_React16时代,该用什么姿势写 React ?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android adapter 按钮隐藏
- 下一篇: vue 文字无缝滚动_手把手教你搭建 V