【翻譯】React 16.3 新的生命週期和context api

文章首發於個人我的github博客html

這裏是原文連接react

一段時間之前,咱們寫了一篇文章有關咱們即將升級咱們遺留的生命週期方法,包含着咱們慢慢的遷移的策略。在React 16.3.0這個版本中,爲了慢慢遷移,咱們增長了一些新的生命週期。咱們也推薦了一些被長期期待的一些特性:一個官方的context api,一個 forwarding ref,一個ergonomic ref。git

Official Context API

這麼長時間以來,React一直提供了一個實驗性的api context.儘管它是一個頗有用的工具,咱們仍是不推薦使用它由於一些隱藏的問題。並且咱們一直計劃去用一個更好的api去替代它。github

16.3這個版本引入了一個新的context api,它更加的高效,並且他支持各類靜態類型檢查和很深層次的更新。
這有一個例子來講明,你能夠想象你注入了了一個「theme」變量去使用新的apiapi

const ThemeContext = React.createContext("light")
class ThemeProvider extends React.Component{
    state = {theme: 'light'}
    render(){
        return (
            <ThemeContext.Provider value={this.state.theme}>
                {this.props.children}
            </ThemeContext.Provider/>
        )
    }
}
class ThemeButton extends React.Component{
    render(){
        return (
            <ThemeContext.Consumer>
                {theme => <Button theme={theme} />}
            </ThemeContext.Consumer>
        )
    }
}複製代碼

createRef Api

之前,react提供兩種方式去管理refs,一個是字符串api,另外一個是經過回調函數。儘管字符串這種方法是兩種中最方便的,可是他有一些不完善的地方,因此咱們官方建議是用回調去替代它。
16.3版本中提供了一個新的選項去管理refs,它和字符串方式同樣便利,卻沒有它的缺點。安全

class MyComponent extends React.Component{
    constructor(props){
        super(props)
        this.inputRef = React.createRef()
    }

    render(){
        return <input type="text" ref={this.inputRef} />
    }

    componentDidMount(){
        this.inputRef.current.focus()
    }
}複製代碼

forwardRef Api

一般,React組件是聲明式的,可是有些時候有不可避免的會使用一些dom節點在組件的實例中。很一般的一些狀況好比管理聚焦,選擇或者動畫。React提供了refs做爲一種方式去解決這個問題。然而,組件封裝提出了一些挑戰。bash

例如,若是你用組件替代了,綁定在原先組件的ref屬性值就開始指向了外層的包裹組件而不是DOM節點(在函數式的組件中將會是null),這就是被稱讚的「application-level」組件就像評論組件同樣須要被包裝,它可以干擾葉子節點,例如FancyButon組件,他們的使用方式就和dom節點同樣,或許他們還會暴露出他們的DOM節點。app

Ref forwarding是一個新的特性,讓許多組件可以接收ref,而且傳給它的子組件。eg:dom

const FancyButton = React.forwardRef((props,ref) => {
    <button ref={ref} className="FancyButton">
        {this.prop.children}
    </button>
})
const ref = React.createRef()
<FancyButton ref={ref}>click,/FancyButton>複製代碼

用這種方式,組建能夠將erf傳遞給DOM button,而且須要的話鏈接它,就像直接在使用一個dom組件。異步

固然,ref forwarding並不只侷限於向葉子組件渲染dom節點,若是你編寫高階組件的話,咱們建議你用它自動的向那些被包裹的組件傳遞ref。

Component Lifecycle Changes

React組件的api已經好久沒有改動了。然而,當咱們添加了一些新特性(出錯處理和異步渲染)以後,咱們延伸出了這種模型儘管他並非咱們最初計劃的。

例如,利用現有的api,很容易就能夠阻止最初的渲染。這是由於有太多的過程去完成一次渲染。咱們研究發現,出錯行爲的處理並無被考慮進去,這樣就會致使內存泄漏。並且如今的組件也讓其餘過程複雜化。

這些問題使得組件的生命週期被濫用。(componentWillMount,componentWillReceiveProps,componentWillUpdate)。並且令咱們困惑的是這些錯誤常常發生在生命週期中。根據這些緣由,咱們決定使用一些更好的選擇。

咱們知道這些改變會影響不少已有的組件。所以,咱們會盡量慢慢的遷移,並且咱們會提供一些別的方法。

咱們爲了放棄這些不安全的生命週期,咱們提供了幾個新的:

  • getDerivedStateFromProps:替代componentWillReceiveProps這個生命週期更加安全的方法
  • getSnapshotBeforeUpdate: 爲了支持在組件更新前更加安全的讀取屬性

最後,附上此次api更新嚐鮮的demo

相關文章
相關標籤/搜索