Context概念
个别用在跨组件通信中。
如下面的组件树中,A组件与B组件之间隔着十分多的组件,如果A组件心愿传递给B组件一个属性,那么不得不应用props将属性从A组件历经一系列两头组件传递给B组件。
这样代码不仅十分的麻烦,更重要的是两头的组件可能压根就用不上这个属性,却要承当一个传递的职责,这是咱们不心愿看见的。
Context呈现的目标就是为了解决这种场景,使得咱们能够间接将属性从A组件传递给B组件。
旧Context(不举荐应用)
过期的API官网文档传送门
根本用法
假设,ABC三个组件,AC为祖孙关系,AB父子关系,当初应用context
由A向C传递属性text
。
class A extends React.Component { getChildContext() { return { text: 'Hello孙子' } } render() { return ( <div>组件A蕴含<B/></div> ) }}A.childContextTypes = { text: PropTypes.string };class B extends React.Component { render() { return ( <div>组件B蕴含<C/></div> ) }}class C extends React.Component { render() { const { text } = this.context; return ( <div>我是C我接管到A传递的内容是{text}</div> ) } }C.contextTypes = { text: PropTypes.string }
注意上述代码中用以提供context
的API
,只有给下层组件增加getChildContext
和childContextTypes
,React
将主动向下传递信息,子树上的所有组件能够通过定义 contextTypes
来拜访 context
。
带来的问题
如果咱们想要更新context
,那么只能通过更新state
或者props
并将其值赋值给context
。
class A extends React.Component { constructor(props) { super(props); this.state = { text: 'Hello孙子' }; } getChildContext() { return { text: this.state } } updateState = () => { this.state = { text: '我是你爷爷' }; } render() { return ( <div onClick={this.updateState} >组件A蕴含<B /></div> ) }}A.childContextTypes = { text: PropTypes.string };
然而,如果A组件提供的一个context
产生了变动,而两头父组件(B)的 shouldComponentUpdate
返回 false
,那么实际上B和C都不会进行更新。应用了context
的组件则齐全失控,所以基本上没有方法可能牢靠的更新context
。
新Context
官网文档传送门
还是上述例子,AC祖孙组件通信。应用createContext
能够构建一个Provider
用以给孙子组件传递props
。
const defaultVal = { text: 'Hello,孙子' };const AContext = React.createContext(defaultVal);class App extends React.Component { constructor(props) { ..., this.state = { text: '这里是新的内容' } } render() { return ( <AContext.Provider value={this.state}> <B /> </AContext.Provider> ) }}// 接管形式1-定义contextTypeimport { AContext } from './A';class C extends React.Component { static contextType = AContext; render() { const { text } = this.context; return ( <div>我是C我接管到A传递的内容是{text}</div> ) } }// 接管形式2-应用consumer// consumer次要用以函数组件渲染import { AContext } from './A';class C extends React.Component { render() { return ( <AContext.Consumer> ({ text }) => ( <p>我是C我接管到A传递的内容是{text}</p> ) </AContext.Consumer> ) } }
Redux中的Context
// 待续补坑