聊一聊如何使用context,這是學習redux原始碼的基礎哦
在學習redux原始碼一段時間之後,我發現不懂得context
如何使用已經阻礙到我理解redux的設計思想了。。
所以,這裡介紹一下react的context
如何使用,不過這個api可能你在業務開發時永遠不會用到。。
好了,廢話不多說,我們來講解下context
如何使用。
一. 如何使用context?
想象一下,我們有現在這樣一個頁面(Index
),其元件樹長成如下這個樣子:
假設這個元件樹裡的任意一個元件都可以去更新Index
中的屬性themeColor
,這個時候就有了狀態提升
的問題,需要把狀態提升到Index
中,然後一級一級傳下來。
這裡的問題是非常明顯的,需要把狀態一級一級傳遞下去,如果元件層次很深的話,可維護性會非常非常差,簡直就是災難。
如果這棵元件樹長這個樣子就好了,所有元件可以去一個公共區域
去獲取狀態,這樣不管元件層次有多深,每個元件都可以去這個公共區域
去獲取狀態。
我們實現一下這個元件樹
class Index extends Component {
render () {
return (
<div>
<Header />
<Main />
</div>
)
}
}
class Header extends Component {
render () {
return (
<div>
<h2>This is header</h2>
<Title />
</div>
)
}
}
class Main extends Component {
render () {
return (
<div>
<h2>This is main</h2>
<Content />
</div>
)
}
}
class Title extends Component {
render () {
return (
<h1>React.js 小書標題</h1>
)
}
}
class Content extends Component {
render () {
return (
<div>
<h2>React.js 小書內容</h2>
</div>
)
}
}
ReactDOM.render(
<Index />,
document.getElementById('root')
)
接下來我們基於以上程式碼,來介紹如何使用context。
class Index extends Component {
static childContextTypes = {
themeColor: PropTypes.string
}
constructor () {
super()
this.state = { themeColor: 'red' }
}
getChildContext () {
return { themeColor: this.state.themeColor }
}
render () {
return (
<div>
<Header />
<Main />
</div>
)
}
}
先宣告一個靜態變數childContextTypes
,這個變數名是固定的。然後,我們在state裡初始化一個狀態,然後在getChildContext
(這個方法名也是固定的)裡設定context
。
以上操作,我們就完成了父元件的context
設定工作,接下來,我們看下在子元件裡如何去取context
。
class Title extends Component {
static contextTypes = {
themeColor: PropTypes.string
}
render () {
return (
<h1 style={{ color: this.context.themeColor }}>React.js 小書標題</h1>
)
}
}
子元件要想獲得context,必須要宣告contextTypes
,這個變數名也是固定的,必須要這樣寫。
接下來,我們就可以在子元件中通過this.context
來獲取context
中的值,可以在父元件中通過this.setState
來修改context中的值。
二. 更直觀地使用context
在最近幾個版本中,React對context
的api
進行了調整,更加明確了生產者消費者
的使用方式。
import React from 'react';
const ThemeContext = React.createContext({
themeColor: 'red',
});
通過靜態方法React.createContext
建立一個context
物件,這個context
物件包含兩個元件:Provider
和Consumer
。
class App extends React.Component {
render () {
return (
<ThemeContext.Provider value={{themeColor: 'green'}}>
<Header />
</ThemeContext.Provider>
);
}
}
Provider
的value
相當於getChildContext()
。
class Header extends React.Component {
render () {
return (
<Title>Hello React Context API</Title>
);
}
}
class Title extends React.Component {
render () {
return (
<ThemeContext.Consumer>
{context => (
<h1 style={{background: context.themeColor}}>
{this.props.children}
</h1>
)}
</ThemeContext.Consumer>
);
}
}
Consumer
的children
必須是一個函式,通過函式的引數獲取Provider
提供的Context
。
三. 總結
新版本的react
裡對context
的api
調整過後,開發者能夠更加直觀地理解context
的使用方式。
四. 參考
https://juejin.im/post/5a90e0545188257a63112977
https://www.jianshu.com/p/c7c47ead84c7
https://react.docschina.org/docs/context.html
https://yepbug.com/2018/11/11/react-context-and-simple-redux/
http://huziketang.mangojuice.top/books/react/lesson29
相關文章
- 從原始碼來聊一聊hashmap原始碼HashMap
- 聊一聊黑客是如何思考問題的黑客
- 聊一聊 AOP :表現形式與基礎概念
- 聊一聊我對 React Context 的理解以及應用ReactContext
- NLP segment-01-聊一聊分詞 AI 的基礎分詞AI
- 聊一聊 EventBus 原始碼和設計之禪原始碼
- 聊一聊如何使用Crank給我們的類庫做基準測試
- 聊一聊 php 程式碼提示PHP
- 聊一聊這個總下載量3603w的xss庫,是如何工作的?
- 聊一聊編碼與亂碼的區別
- 淺聊同源策略的一些基礎
- 通過Redux原始碼學習基礎概念一:簡單例子入門Redux原始碼單例
- 聊一聊這個總下載量36039K的XSS-NPM庫,是如何工作的?NPM
- 聊一聊Oracle的Tablespace(一)Oracle
- 聊一聊 JVM 的 GCJVMGC
- 聊一聊 RestTemplateREST
- 聊一聊 cookieCookie
- 聊一聊遊戲的壓測遊戲
- 聊一聊 Javascript 中的 ASTJavaScriptAST
- 聊一聊 TLS/SSLTLS
- 再問分級診療,聊模式還是聊如何落地?模式
- 聊一聊Java的列舉enumJava
- 聊一聊Redis的離線分析Redis
- 聊一聊MySQL的字符集MySql
- 聊一聊MySQL的儲存引擎MySql儲存引擎
- 簡單聊一聊Vuex的原理Vue
- 聊一聊Javascript中的Promise物件JavaScriptPromise物件
- 聊一聊MySQL的直方圖MySql直方圖
- 聊一聊資料庫基準測試那些事資料庫
- 聊一聊前端換膚前端
- 聊一聊Greenplum與PostgreSQLSQL
- 聊一聊模板方法模式模式
- 聊一聊測試流程
- 聊一聊session和cookieSessionCookie
- 聊一聊JWT與sessionJWTSession
- 聊一聊宣告式介面呼叫與Nacos的結合使用
- 聊一聊如何截獲 C# 程式產生的日誌C#
- Android、IOS雙端一對一語音聊和一對一視訊聊APP,含原始碼AndroidiOSAPP原始碼