冰琪儿 發表於 2020-4-20 16:15:00

React Context 的基本用法

<p>Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。</p>
<h2 id="1-用法">1. 用法</h2>
<h3 id="reactcreatecontext">React.createContext</h3>
<pre><code>const MyContext = React.createContext(defaultValue);
</code></pre>
<p>创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。</p>
<p>只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。这有助于在不使用 Provider 包装组件的情况下对组件进行测试。注意:将 undefined 传递给 Provider 的 value 时,消费组件的 defaultValue 不会生效。</p>
<h3 id="contextprovider">Context.Provider</h3>
<pre><code>&lt;MyContext.Provider value={/* 某个值 */}&gt;
</code></pre>
<p>每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。</p>
<p>Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。</p>
<h3 id="contextconsumer">Context.Consumer</h3>
<pre><code>&lt;MyContext.Consumer&gt;
{value =&gt; /* 基于 context 值进行渲染*/}
&lt;/MyContext.Consumer&gt;
</code></pre>
<p>这里,React 组件也可以订阅到 context 变更。这能让你在函数式组件中完成订阅 context。</p>
<h2 id="2-实例应用">2. 实例应用</h2>
<p><img src="https://images.cnblogs.com/cnblogs_com/cckui/1532364/o_2004200754131587369244781.jpg" alt="image" loading="lazy"></p>
<p>如图,在父组件中定义两个变量:fruit 和 count。子组件可以拿到父组件的fruit,子子组件可以拿到父组件的 fruit,并且可以改变count的值。</p>
<h4 id="实现步骤如下">实现步骤如下:</h4>
<h3 id="21-新建文件-contextjs">2.1 新建文件 context.js</h3>
<p>创建一个Context 对象,并导出Provider和Consumer容器。</p>
<pre><code>import { createContext } from 'react'

export const { Provider, Consumer } = createContext()

</code></pre>
<h3 id="22-新建父组件-indexjs">2.2 新建父组件 index.js</h3>
<pre><code>import React, { Component } from 'react'
import { Provider } from './context' // 引入Provider
import Son from './Son' // 引入子组件

class Main extends Component {
constructor(props) {
    super(props)
    this.state = {
      fruit: 'apple',
      count: 0,
    }
}

componentDidMount() {}

getContext = () =&gt; {
    const { fruit, count } = this.state
    return {
      fruit,
      countUtil: {
      addCount: num =&gt; {
          this.setState({
            count: count + num,
          })
      },
      delCount: num =&gt; {
          this.setState({
            count: count - num,
          })
      },
      },
    }
}

render() {
    const { fruit, count } = this.state
    return (
      // Provider 容器, 其value接收一个getContext方法
      &lt;Provider value={this.getContext()}&gt;
      父组件 fruit = {fruit}, count = {count}
      &lt;hr /&gt;
      &lt;Son /&gt;
      &lt;/Provider&gt;
    )
}
}

export default Main

</code></pre>
<h3 id="23-新建子组件-sonjs">2.3 新建子组件 Son.js</h3>
<pre><code>import React, { Component } from 'react'
import { Consumer } from './context' // 引入Consumer
import GrandSon from './GrandSon' // 引入子子组件

class Main extends Component {
constructor(props) {
    super(props)
    this.state = {}
}

render() {
    return (
      // Consumer 容器,可以拿到父组件传递下来的 fruit 属性, 并可以展示对应的值
      &lt;Consumer&gt;
      {context =&gt; (
          &lt;div&gt;
            子组件 fruit={context.fruit}
            &lt;hr /&gt;
            &lt;GrandSon /&gt;
          &lt;/div&gt;
      )}
      &lt;/Consumer&gt;
    )
}
}

export default Main

</code></pre>
<h3 id="24-新建子子组件-grandsonjs">2.4 新建子子组件 GrandSon.js</h3>
<pre><code>import React, { Component } from 'react'
import { Consumer } from './context' // 引入Consumer

class Main extends Component {
constructor(props) {
    super(props)
    this.state = {}
}

render() {
    return (
      // Consumer 容器,可以拿到父组件传递下来的 fruit 属性, 以及 countUtil对象下的 addCount 和 delCount 方法
      &lt;Consumer&gt;
      {context =&gt; (
          &lt;div&gt;
            子子组件 fruit={context.fruit}
            &lt;br /&gt;
            &lt;button type="button" onClick={() =&gt; context.countUtil.addCount(2)}&gt;
            加2
            &lt;/button&gt;
            &amp;nbsp;
            &lt;button type="button" onClick={() =&gt; context.countUtil.delCount(3)}&gt;
            减3
            &lt;/button&gt;
            &lt;hr /&gt;
          &lt;/div&gt;
      )}
      &lt;/Consumer&gt;
    )
}
}

export default Main

</code></pre><br><br>
来源:https://www.cnblogs.com/cckui/p/12738466.html
頁: [1]
查看完整版本: React Context 的基本用法