2021-02-25

React Context 理解和使用

写在前面

​ 鉴于笔者学习此内容章节 React官方文档 时感到阅读理解抽象困难,所以决定根据文档理解写一篇自己对Context的理解,文章附带示例,以为更易于理解学习。更多内容请参考 React官方文档

​ 如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是笔者创作的最大动力!

​ 如果发现文章有问题也可以在文章下方及时联系笔者哦,相互探讨一起进步~

基本概念

  • ContextReact中为了避免在不同层级组件中逐层传递props的产物,在没有Context的时候父组件向子组件传递props属性只能在组件树上自上而下进行传递,但是有些属性并不是组件树的每层节点都有相同的需求,这样我们再这样逐层传递props就显得代码很繁琐笨重。
  • 使用React.createContext(defulData)可以通过创建一个ContextObject,在某个组件中调用ContextObject.Provider同时可以设置新的value = newData覆盖掉defulData共享到下面的所有子组件,需要ContextObject共享出来的数据的子组件可以通过static contextType = ContextObject接收到data,使用this.context即可调用data

适用场景

  • 很多不同层级的组件需要访问同样的数据,所以如果我们只是想避免层层传递一些属性,那么我们还有更好的选择: 组合组件

Context API 理解与运用

  • React.createContext(defaultValue)
    创建一个Context对象,defaultValue是默认参数,在一个组件中可以调用这个对象的ProviderAPI,并且设置新的参数:
const Context = React.createContext(defaultValue)function ContextProvider () { return ( 	<Context.Provider value = { newValue }>		 /* 子组件(这里的组件及其子组件都可以收到这个Context对象发出的newValue) */		<Context.Provider/> )}

​ 但是如果没有对应的Context.Provider相匹配,那么组件树上的所有组件都可以收到这个Context对象发出 的defaultValue

​ 同时可以调用ContextConsumerAPI可以用来接受到Context的值,并且根据这个值渲染组件:

function ContextConsumer () { return ( 	<Context.Comsumer>   {value =>    	<div>   		/* 可以根据value进行渲染 */  		</div>   }  </Context.Comsumer> )}
  • Context.Provider & Context.Comsumer

    • <MyContext.Provider value={ variableValue }>可以允许消费组件订阅到variableValue 值的变化,也就是说消费组件可以根据variableValue值的变化而变化,variableValue的值我们可以定义一个事件来控制改变;

    <MyContext.Consumer> {value => /* 基于 context 值进行渲染*/}</MyContext.Consumer>

    利用Context.Consumer API 可以让我们即使是在函数式组件也可以订阅到 Context的值;

    这种方法需要一个函数作为子元素,函数接收当前的context值,并返回一个 React 节点。

    传递给函数的 value 值等价于组件树上方离这个 context 最近的 Provider 提供的 variableValue 值。如果没有对应的 Provider,value 参数等同于传递给 createContext()defaultValue

    // Provider 结合 Consumer 使用示例import React from 'react';import ReactDOM from 'react-dom';import './index.css';// 创建 Context 对象const MyContext = React.createContext(0) // defaultValue 是数字0// App组件 渲染 Context 对象class App extends React.Component { constructor(props){  super(props);  this.state = {   variableValue : 0  }  // 处理 Provider中value变化的函数  this.handleChange = () => {   this.setState(state => ({    variableValue: state.variableValue + 1    })   )  } } render(){  return (   // 调用 Context.Provider, 设置可以让Consumer组件监听变化的 value 值    <MyContext.Provider value = {this.state.variableValue}>     <Context changeValue = {this.handleChange}/>    </MyContext.Provider>  ) }}// 消费组件class Context extends React.Component{ render(){  return (   <MyContext.Consumer>    /* 根据Context的value进行渲染 */    {value =>      <button onClick={this.props.changeValue} >       Add MyValue:{value}      </button>    }   </MyContext.Consumer>  ) }}ReactDOM.render(  <App className = 'app'/>, document.getElementById('root'));

    当Provider的 variableValue值发生变化时,它内部的所有消费组件都会重新渲染。

  • Class.contextType

    class MyClass extends React.Component { render() { let value = this.context; // this.context 可以访问到 MyClass 的contextType /* 基于 MyContext 组件的值进行渲染 */ }}MyClass.contextType = MyContext; //将MyClass的contextType属性赋值为 Context 对象的值

    挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。此属性能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。

    注: 从文档的字面意思,Class.contextType类组件特有的API,所以函数式组件只能使用 Context.Consumer来访问 Context对象的值,我们可以来试一下类组件和函数式组件的API:

    import React from 'react';import ReactDOM from 'react-dom';import './index.css';// 创建 Context 对象const MyContext = React.createContext(0)// App组件 渲染 Context 对象class App extends React.Component { constructor(props){  super(props);  this.state = {   variableValue : 0  }  this.handleChange = () => {   this.setState(state => ({    variableValue: state.variableValue + 1    })   )  } } render(){  return (   // 调用 Context.Provider, 设置可以让Consumer组件监听变化的 value 值    <MyContext.Provider value = {this.state.variableValue}>     <Context_consumer changeValue = {this.handleChange} />     <br/>     <Context_contextType changeValue = {this.handleChange} />     <br />     <Func_Consumer changeValue = {this.handleChange} />     <br />     <func_contextType changeValue = {this.handleChange} />    </MyContext.Provider>  ) }}// Class & Consumer 消费组件class Context_consumer extends React.Component{ render(){  return (   <MyContext.Consumer>    {value =>      <button onClick={this.props.changeValue} >       Add Class_consumer:{value}      </button>    }   </MyContext.Consumer>  ) }}// Class & contextType 的消费组件class Context_contextType extends React.Component{ render(){  let value = this.context  return (     <button onClick={this.props.changeValue} >      Add Class_contextType:{value}     </button>  ) }};Context_contextType.contextType = MyContext;// 函数组件 & Consumerfunction Func_Consumer (props) { return (  <MyContext.Consumer>   {value =>    <button onClick={props.changeValue} >     Add Func_consumer:{value}    </button>   }  </MyContext.Consumer> )}// 函数组件 & contextTypefunction func_contextType (props) { let value = this.context return (  <button onClick={props.changeValue} >   Add func_contextType:{value}  </button> )}func_contextType.contextType = MyContext;ReactDOM.render(  <App className = 'app'/>, document.getElementById('root'));

    运行结果:
    除了func_contextType组件之外其他组件都可以正常运行









原文转载:http://www.shaoqun.com/a/587587.html

跨境电商:https://www.ikjzd.com/

贝恩投资公司:https://www.ikjzd.com/w/1336

聚贸:https://www.ikjzd.com/w/1305


写在前面​ 鉴于笔者学习此内容章节React官方文档时感到阅读理解抽象困难,所以决定根据文档理解写一篇自己对Context的理解,文章附带示例,以为更易于理解学习。更多内容请参考React官方文档​ 如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是笔者创作的最大动力!​ 如果发现文章有问题也可以在文章下方及时联系笔者哦,相互探讨一起进步~基本概念Context是React中为了
crowd:https://www.ikjzd.com/w/880
海鹰数据:https://www.ikjzd.com/w/2539
母婴团购网:https://www.ikjzd.com/w/716
跨境电商新模式,无数卖家疯狂涌入!:https://www.ikjzd.com/home/23051
亚马逊新手卖家应如何选择产品?:https://www.ikjzd.com/home/132261
关于亚马逊二审那些事儿,亚马逊二审问题详解!:https://www.ikjzd.com/home/104818

No comments:

Post a Comment