本例只是做說明性,具體代碼要運行起來,還需要加入些其他元素
主要解決的問題
在應用中可能會有很多組件會去使用到的組件,並且當使用父子傳遞這一機制的時候,會顯得過於臃腫繁瑣,所以要使用上下文的方式來進行傳遞。
1.創建一個context
// theme-context.js
import React from 'react'
export const ThemeContext = React.createContext('dark') // 默認爲dark
2.使用context內容-class
// Demo.js
import { ThemeContext } from './theme-context'
class Demo extends React.Component {
render () {
const theme = this.context
return (<div>{theme}</div>)
}
}
Demo.contextType = ThemeContext
2.使用context內容-function
// Demo.js
import { ThemeContext } from './theme-context'
function Consumer (props) {
return (
<ThemeContext.Consumer>
{theme => (
<div>{theme}</div>
)}
</ThemeContext.Consumer>
)
}
3.傳遞啓用
// App.js
import React from 'react'
import { ThemeContext } from './theme-context'
import Demo from 'demo'
function Wrapper (props) {
return (<Demo />)
}
class App extends React.Component {
render (
return (
<div>
<ThemeContext.Provider value="light">
<Wrapper /> // 此時 Wrapper 內的 Demo 使用的是就近的 light
</ThemeContext.Provider>
<Wrapper /> // 此時 Wrapper 內的 Demo 使用的是默認值 dark
</div>
)
)
}
在hook中使用context
父組件還是要使用<MyContext.Provider value={} />
這種方式將上下文對象全局傳遞出去,不同的就是使用到context的組件,可以使用function組件,來方便的接收
// Demo.js
import React from 'react'
import { ThemeContext } from './theme-context'
function Demo (props) {
const theme = React.useContext(ThemeContext)
// ... context中變化時,該組件會同步刷新
}
需要注意的問題
context會使用參考標識,也就是說,可能value不變的情況下,他會通知使用到context組件重新渲染
<Provider value={{something: 'something'}}>
<Toolbar />
</Provider>
// 此時此組件刷新的時候,他會通知組件 value發生了改變(儘管字面量並沒有發生改變)
// 可以將value的值提到state中去存儲
state = {
value: {something: 'something'}
}
<Provider value={this.state.value}>
<Toolbar />
</Provider>