Context API總是很讓人迷惑。這個API是官方的,但是官方又不希望開發者使用這個API,說是這個API會在以後改變。現在就是那個改變的時刻。新的API已經被merge了。而且它看起來更加的「用戶友好」了。尤其是你必須使用redux、mobx的時候,可以選擇新的Context API實作更簡單的狀態管理。
新的API用起來非常的簡單:React.createContext()
,這樣就建立了兩個元件:
import {createContext} from 'react'; const ThemeContext = createContext({ background: 'yellow', color: 'white' });
呼叫createContext
方法會傳回兩個對象,一個是Provider
,一個是Consumer
。
那個Provider
是一個特殊的元件。它可以用來給子樹裡的元件提供資料。一個例子:
class Application extends React.Component { render() { <ThemeContext.Provider value={{background: 'black', color: 'white'}}> <Header /> <Main /> <Footer /> </ThemeContext.Provider> } }
上例展示如何傳遞「theme」 context的。當然這些值可以是動態的(例如,基於this.state
)。
下一步就是使用Consumer
。
const Header = () => { <ThemeContext.Consumer> {(context) => { return ( <p style={{background: context.background, color: context.color}}> Welcome! </p> ); }} </ThemeContext.Consumer> }
如果在render Consumer
的時候沒有嵌套在一個Provider
裡面。那麼就會使用createContext
方法呼叫的時候設定的預設值。
注意:
Consumer必須可以存取到同一個Context#元件。如果你要建立一個新的context,用的是同樣的入參,那麼這個新建的context的資料是無法存取的。因此,可以把Context當做一個元件,它可以創建一次,然後可以export,可以import。
這個新的語法用了function as child模式(有時也叫render prop模式)。如果不是很熟悉這個模式,那麼推薦你來看這些文章。
新的API不再要求你宣告contextProps
了。
Context傳遞的資料和Context.Provider
元件的value
屬性是一樣的。對Provider
資料的修改會造成所有的消費者(consumer)重繪。
參考這個RFC。新的聲明週期方法會被引入,而舊的會被廢棄。
這項改變主要是為了強制推行最佳實踐。你可以看看這篇文章來了解為什麼這些生命週期方法會變得很詭異。這些最佳模式在React 16的非同步繪圖模式(Async Mode)下顯得非常重要。
要被廢棄的方法:
componentWillMount
--使用componentDidMount
#componentWillUpdate
--使用componentDidUpdate
代替
componentWillReceiveProps
--使用一個新的方法:static getDerivedStateFromProps
來代替。
不過這些並不會立刻發生,他們可以用到React 16.4。在React 17裡將被徹底移除。如果你開啟了StrictMode
或AsyncMode
,可以用這樣的方式來使用,但會收到警告:
UNSAFE_componentWillMount
UNSAFE_componentWillReceiveProps
UNSAFE_componentWillUpdate
#UNSAFE_componentWillUpdate
static getDerivedStateFromProps當
我們需要其他的方式根據props的變動更新state。社群決定引入一個新的static
方法來處理這個問題。 什麼是靜態方法?一個靜態方法就是存在於類別內,而不是類別的實例內的方法。靜態方法存取不到this,並且在聲明的時候有
關鍵字在前面修飾。 但是,問題來了。既然這個方法沒有辦法存取
呢?答案就是,不呼叫
。這個方法直接傳回需要更新的state的數據,或傳回null,如果沒有什麼需要更新的話。
static getDerivedStateFromProps(nextProps, prevState) { if(nextProps.currentRow === prevState.lastRow) { return null; } return { lastRow: nextProps.currentRow, isCrollingDown: nextProps.curentRow > prevState.lastRow } }
呼叫這個方法和之前呼叫this.setState
的效果是一樣的。只會修改這些傳回的值,如果是null的話則不修改state。 state的其他值都會保留。 值得注意的事
你要定義初始state的值。無論是在constructor
裡,或是類別屬性。否則會報警告。 這個方法
會在第一次掛載和重繪的時候都會呼叫到,因此你基本上不用在constructor裡根據傳入的props來setState
。
如果定義了getDerivedStateFromProps
後,又定義了
ComponentName.getDerivedStateFromProps = (nextProps, prevState) => { // Your code here }
严格模式是一个新的方式来确保你的代码是按照最佳实践开发的。它实际是一个在React.StrictMode
下的组件。它可以用在你的组件树的任何一部分上。
import {StrictMode} from 'react' class Application extends React.Component { render() { return ( <StrictMode> <Context.Provider value={{background: 'black', color: 'white'}}> <Header /> <Main /> <Footer /> </Context.Provider> </StrictMode> ); } }
如果一个在StricMode
子树里的组件使用了componentWillMount
方法,那么你会看到一个报错消息。
异步模式在React.unsafe_AsyncMode
下。使用AsncMode
也会打开StrictMode
模式下的警告。
相关推荐:
以上是React 16.3新特性分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!