React的Context的使用方法简介
<p><strong><span style="font-size: 14pt">context </span></strong></p><p><span style="font-size: 18px">定义: Context提供了一种方式,能够让数据在组件树中传递,而不必一级一级手动传递。</span></p>
<p><span style="font-size: 18px">API : createContext(defaultValue?)。</span></p>
<p><strong><span style="font-size: 18px">使用方法:</span></strong></p>
<p><span style="font-size: 18px">首先要引入</span><strong><span style="font-size: 18px">createContext</span></strong></p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">import React, { Component, createContext } from 'react';</span></pre>
</div>
<p> </p>
<p><span style="font-size: 16px"> 然后创建一个Context </span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">const BatteryContext = createContext();</span></pre>
</div>
<p> </p>
<p><span style="font-size: 16px">然后用BatteryContext.Provider包裹组件并且传递属性值。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 16px"><BatteryContext.Provider value={60}>
<Middle /> //子组件
</BatteryContext.Provider></span></pre>
</div>
<p> </p>
<p><span style="font-size: 18px"><span style="font-size: 16px"> 为了方便看出效果,将定义一个子组件和一个孙组件。然后不通过子组件,孙组件直接取值</span>。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">import React, { Component, createContext } from 'react'<span style="color: rgba(0, 0, 0, 1)">;
const BatteryContext </span>=<span style="color: rgba(0, 0, 0, 1)"> createContext();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明一个孙组件</span>
<span style="color: rgba(0, 0, 0, 1)">class Leaf extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
)
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明一个子组件</span>
<span style="color: rgba(0, 0, 0, 1)">class Middle extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <Leaf />
<span style="color: rgba(0, 0, 0, 1)">}
}
class App extends Component {
render(){
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Provider value={60}>
<Middle />
</BatteryContext.Provider>
<span style="color: rgba(0, 0, 0, 1)"> );
}
}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> App;</span></pre>
</div>
<p> </p>
<p><span style="font-size: 16px">孙组件需要BatteryContext.Consumer来接收值,Consumer里面不能直接渲染其他组件,而是要声明一个函数。函数的参数就是context的值。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 16px"><span style="color: rgba(0, 0, 0, 1)">class Leaf extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Consumer><span style="color: rgba(0, 0, 0, 1)">
{
battery </span>=> <h1>Battery : {battery}</h1>
<span style="color: rgba(0, 0, 0, 1)"> }
</span></BatteryContext.Consumer>
<span style="color: rgba(0, 0, 0, 1)"> )
}
}</span></span></pre>
</div>
<p> </p>
<p><span style="font-size: 16px"> 效果图;</span></p>
<p><img src="https://img2018.cnblogs.com/blog/1557620/201907/1557620-20190721155550531-814465393.jpg" alt=""></p>
<p> </p>
<p><span style="font-size: 16px">这样没通过Middle组件来传递值,但是Leaf组件能通过context来获得属性。这就是context的基本用法。</span></p>
<p> </p>
<div><strong><span style="font-size: 14pt">context不但能跨层级来传递属性值,还能在属性值发生变化的时候重渲染Consumer下面的元素,举个例子:</span></strong></div>
<div> </div>
<div><span style="font-size: 16px">在state中定义battery并赋值</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">state =<span style="color: rgba(0, 0, 0, 1)"> {
battery: </span>60<span style="color: rgba(0, 0, 0, 1)">
}</span></span></pre>
</div>
<p> </p>
</div>
<div><span style="font-size: 16px">然后做一个按钮,每次点击的时候都要battery减一。 代码:</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px"><span style="color: rgba(0, 0, 0, 1)">render() {
const { battery } </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Provider value={battery}>
<<span style="color: rgba(0, 0, 0, 1)">button
type</span>="button"<span style="color: rgba(0, 0, 0, 1)">
onClick</span>={() => <span style="color: rgba(0, 0, 255, 1)">this</span>.setState({ battery: battery - 1<span style="color: rgba(0, 0, 0, 1)"> })}
</span>><span style="color: rgba(0, 0, 0, 1)">
减减
</span></button>
<Middle />
</BatteryContext.Provider>
<span style="color: rgba(0, 0, 0, 1)"> );
}</span></span></pre>
</div>
<p> </p>
</div>
<div><span style="font-size: 16px">全部代码:</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">import React, { Component, createContext } from 'react'<span style="color: rgba(0, 0, 0, 1)">;
const BatteryContext </span>=<span style="color: rgba(0, 0, 0, 1)"> createContext();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明一个孙组件</span>
<span style="color: rgba(0, 0, 0, 1)">class Leaf extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Consumer><span style="color: rgba(0, 0, 0, 1)">
{
battery </span>=> <h1>Battery : {battery}</h1>
<span style="color: rgba(0, 0, 0, 1)"> }
</span></BatteryContext.Consumer>
<span style="color: rgba(0, 0, 0, 1)"> )
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明一个子组件</span>
<span style="color: rgba(0, 0, 0, 1)">class Middle extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <Leaf />
<span style="color: rgba(0, 0, 0, 1)">}
}
class App extends Component {
state </span>=<span style="color: rgba(0, 0, 0, 1)"> {
battery: </span>60<span style="color: rgba(0, 0, 0, 1)">
}
render() {
const { battery } </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Provider value={battery}>
<<span style="color: rgba(0, 0, 0, 1)">button
type</span>="button"<span style="color: rgba(0, 0, 0, 1)">
onClick</span>={() => <span style="color: rgba(0, 0, 255, 1)">this</span>.setState({ battery: battery - 1<span style="color: rgba(0, 0, 0, 1)"> })}
</span>><span style="color: rgba(0, 0, 0, 1)">
减减
</span></button>
<Middle />
</BatteryContext.Provider>
<span style="color: rgba(0, 0, 0, 1)"> );
}
}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> App;</span></pre>
</div>
<p> </p>
</div>
<p><span style="font-size: 16px"> 效果图: </span></p>
<p><img src="https://img2018.cnblogs.com/blog/1557620/201907/1557620-20190721160107492-769117216.jpg" alt=""></p>
<p> </p>
<p><span style="font-size: 18px">这样每次点击都会使battery得数值发生变化,从而重渲染Consumer下面的元素。</span></p>
<p> </p>
<div><strong><span style="font-size: 14pt">如果有多个Context该怎么做呢?我们在创建一个 Context</span></strong></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">const OnLineContext = createContext();</span></pre>
</div>
<p> </p>
<div><span style="font-size: 16px">如果有多个context变量的话,只需要把Privider嵌套进来即可,顺序不重要。接下来声明online的Provider了。</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px"><span style="color: rgba(0, 0, 0, 1)">class App extends Component {
state </span>=<span style="color: rgba(0, 0, 0, 1)"> {
battery: </span>60<span style="color: rgba(0, 0, 0, 1)">,
online: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
}
render() {
const { battery, online } </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Provider value={battery}>
<OnLineContext.Provider value={online} >
<<span style="color: rgba(0, 0, 0, 1)">button
type</span>="button"<span style="color: rgba(0, 0, 0, 1)">
onClick</span>={() => <span style="color: rgba(0, 0, 255, 1)">this</span>.setState({ battery: battery - 1<span style="color: rgba(0, 0, 0, 1)"> })}
</span>><span style="color: rgba(0, 0, 0, 1)">
减减
</span></button>
<<span style="color: rgba(0, 0, 0, 1)">button
type</span>="button"<span style="color: rgba(0, 0, 0, 1)">
onClick</span>={() => <span style="color: rgba(0, 0, 255, 1)">this</span>.setState({ online: !<span style="color: rgba(0, 0, 0, 1)">online })}
</span>><span style="color: rgba(0, 0, 0, 1)">
Switch
</span></button>
<Middle />
</OnLineContext.Provider>
</BatteryContext.Provider>
<span style="color: rgba(0, 0, 0, 1)"> );
}</span></span></pre>
</div>
<p> </p>
</div>
</div>
<div><span style="font-size: 16px">与Provider类似。Consumer也需要嵌套,顺序不重要。只要Consumer需要声明函数,所以要注意语法。</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px"><span style="color: rgba(0, 0, 0, 1)">class Leaf extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Consumer><span style="color: rgba(0, 0, 0, 1)">
{
battery </span>=><span style="color: rgba(0, 0, 0, 1)"> (
</span><OnLineContext.Consumer><span style="color: rgba(0, 0, 0, 1)">
{
online </span>=> <h1>Battery : {battery} , Online : {online.toString()}</h1>
<span style="color: rgba(0, 0, 0, 1)"> }
</span></OnLineContext.Consumer>
<span style="color: rgba(0, 0, 0, 1)"> )
}
</span></BatteryContext.Consumer>
<span style="color: rgba(0, 0, 0, 1)"> )
}
}</span></span></pre>
</div>
<p><span style="font-size: 16px"> </span></p>
</div>
<p><span style="font-size: 16px"> 全部代码:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">import React, { Component, createContext } from 'react'<span style="color: rgba(0, 0, 0, 1)">;
const BatteryContext </span>=<span style="color: rgba(0, 0, 0, 1)"> createContext();
const OnLineContext </span>=<span style="color: rgba(0, 0, 0, 1)"> createContext();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明一个孙组件</span>
<span style="color: rgba(0, 0, 0, 1)">class Leaf extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">与Provider类似。Consumer也需要嵌套,顺序不重要。只要Consumer需要声明函数,所以要注意语法。</span>
<BatteryContext.Consumer><span style="color: rgba(0, 0, 0, 1)">
{
battery </span>=><span style="color: rgba(0, 0, 0, 1)"> (
</span><OnLineContext.Consumer><span style="color: rgba(0, 0, 0, 1)">
{
online </span>=> <h1>Battery : {battery} , Online : {online.toString()}</h1>
<span style="color: rgba(0, 0, 0, 1)"> }
</span></OnLineContext.Consumer>
<span style="color: rgba(0, 0, 0, 1)"> )
}
</span></BatteryContext.Consumer>
<span style="color: rgba(0, 0, 0, 1)"> )
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明一个子组件</span>
<span style="color: rgba(0, 0, 0, 1)">class Middle extends Component {
render() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <Leaf />
<span style="color: rgba(0, 0, 0, 1)">}
}
class App extends Component {
state </span>=<span style="color: rgba(0, 0, 0, 1)"> {
battery: </span>60<span style="color: rgba(0, 0, 0, 1)">,
online: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
}
render() {
const { battery, online } </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">接下来声明online的Provider了。如果有多个context变量的话,只需要把Privider嵌套进来即可,顺序不重要。</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><BatteryContext.Provider value={battery}>
<OnLineContext.Provider value={online} >
<<span style="color: rgba(0, 0, 0, 1)">button
type</span>="button"<span style="color: rgba(0, 0, 0, 1)">
onClick</span>={() => <span style="color: rgba(0, 0, 255, 1)">this</span>.setState({ battery: battery - 1<span style="color: rgba(0, 0, 0, 1)"> })}
</span>><span style="color: rgba(0, 0, 0, 1)">
减减
</span></button>
<<span style="color: rgba(0, 0, 0, 1)">button
type</span>="button"<span style="color: rgba(0, 0, 0, 1)">
onClick</span>={() => <span style="color: rgba(0, 0, 255, 1)">this</span>.setState({ online: !<span style="color: rgba(0, 0, 0, 1)">online })}
</span>><span style="color: rgba(0, 0, 0, 1)">
Switch
</span></button>
<Middle />
</OnLineContext.Provider>
</BatteryContext.Provider>
<span style="color: rgba(0, 0, 0, 1)"> );
}
}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> App;</span></pre>
</div>
<p> </p>
<p><span style="font-size: 16px">效果图:</span></p>
<p><img src="https://img2018.cnblogs.com/blog/1557620/201907/1557620-20190721160703650-408113861.jpg" alt=""></p>
<p> </p>
<p> </p>
<div><strong><span style="font-size: 18px">还有一个问题 , 如果Consumer向上找不到对应的Provider怎么办?</span></strong></div>
<div> </div>
<div>
<div><strong><span style="font-size: 18px">其实即使找不到也不会报错,而是显示为空。那怎么设置默认值呢?</span></strong></div>
<div> </div>
</div>
<div><span style="font-size: 16px">那上面的demo举例 ,刚才我们设置的battery为60。如果Consumer向上找不到BatteryContext.Provider的值,我们可以这样设置默认值:</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 16px">const BatteryContext = createContext(30);</span></pre>
</div>
<div><span style="font-size: 16px">这样BatteryContext.Consumer向上找不到值,就会取默认值30。</span></div>
</div>
<p> </p>
<div>
<div><strong><span style="font-size: 18px">context不仅仅只是可以传数值,也可以传函数。大家可以试试看。</span></strong></div>
<div><strong><span style="font-size: 18px">最后再提示一下大家,不要滥用context,不然会影响组件的独立性。 如果一个组件中只使用一个Context的话,就可以使用contextType代替Consumer。详见https://www.cnblogs.com/littleSpill/p/11221817.html</span></strong></div>
<div> </div>
<div> </div>
<div> </div>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/littleSpill/p/11221538.html
頁:
[1]