前言
react的新特性之Context
react更新过后出现了以下几个新特性:
- Context
- ContextType
- lazy
- Suspense
- Memo
下面进一步的对几个新特性的----呀呀呀 -搞它~~哒哒哒
ConText概念
这个api是一种全局变量的感觉,context提供了一种方式,能够让数据在组建树中传递而不必一级一级的手动传递,但是这样的话虽然免去了中间组件对一些自己本身用不到的值传递,但是这样类似全局变量的做法,复用性差,但存在即合理,肯定有一些时候会用到哒~~等俺自己慢慢发现吧
ConText结构
Provider组件会像后代组件统一提供变量值,但是后代组件不能直接获取变量值,因为没有途径,所以Context实例又派生出另一个组件Consumer(消费者),Provider和Consumer之间是任意层级的react组件,所以这样我们就可以看出来Consumer一定是Provider的后代元素。
创建ConText实例对象方法
- createContext(defaultValue?)
是唯一一个途经创建Context实例对象的方式,可以传入一个参数,相当于默认值,但是大多数的情况下是不需要传的。
ConText实例-代码
import React,{Component,createcontext} from 'react';
const BatteryContext =createContext();
class Leaf extends Component{
render(){
return (
//在Consumer里面不能直接渲染生成组件,必须声明一个函数,函数的唯一参数就是这个Context的值,我们这里定义为battery
<BatteryContext.Consumer>{
battery=> <h1> Battery:{battery}</h1>
}</BatteryContext.Consumer>
)
}
}
//中间组件
class Middle extends Component{
render(){
return <Leaf/>;
}
}
class App extends Component{
render(){
return(
<BatteryContext.Provider value={60}>
<Middle/>
</BatteryContext.Provider>
)
}
{
虽然我们没有直接像Leaf组件传递属性,到那时依然可以获取到值,这样我们就能打印出如下图
以上就是Context的基本用法,不仅可以实现跨层级组件传值,还可以再值发生改变的时候,重新渲染。
下面是可变化的代码实例
import React,{Component,createcontext} from 'react';
const BatteryContext =createContext();
class Leaf extends Component{
render(){
return (
<BatteryContext.Consumer>{
battery=> <h1> Battery:{battery}</h1>
}</BatteryContext.Consumer>
)
}
}
//中间组件
class Middle extends Component{
render(){
return <Leaf/>;
}
}
class App extends Component{
state={
battery:60
}
render(){
//解构出来
const { battery }=this.state;
return(
<BatteryContext.Provider value={battery}>
<button
type='button'
onClick={()=>this.setState({battery:battery - 1})}></button>
<Middle/>
</BatteryContext.Provider>
)
}
{
得到如图所示:
以上是针对一个Context的实例,下面对存在多个Context的实例进行实例分析:
import React,{Component,createcontext} from 'react';
const BatteryContext =createContext();
const OnlineContext =createContext();
class Leaf extends Component{
render(){
return (
//与嵌套的Provider相似,只需要嵌套起来即可,顺序依然不重要,但是语法不一样,Consumer需要声明函数
<BatteryContext.Consumer>
{
battery=>(
<BatteryContext.Consumer>
{
online=> <h1> Battery:{battery};online:{String(online)}</h1>
}
</BatteryContext.Consumer>
)
}
</BatteryContext.Consumer>
)
}
}
//中间组件
class Middle extends Component{
render(){
return <Leaf/>;
}
}
class App extends Component{
state={
online:false
battery:60
}
render(){
//解构出来
const { battery ,online}=this.state;
return(
//如果有多个Context的情况下,只需要吧Provider嵌套起来就好,顺序不重要
<BatteryContext.Provider value={battery}>
<OnlineContext.Provider value={online}>
<button type='button' onClick={()=>this.setState({battery:battery - 1})}>battery</button>
<button type='button' onClick={()=>this.setState({online:!online - 1})}>Online</button>
<Middle/>
</OnlineContext.Provider>
</BatteryContext.Provider>
)
}
{
假如我们完成上述的实例后,我们消费者的Consumer向上找不到他所对应的Provider,也就是我们现在
<BatteryContext.Provider>这个组件注释掉,就会出现一个问题,打印出的结果中取不到battery的值,但是并不报错,这个时候我们就需要前面提到的- createContext(defaultValue?),如下所示
//这样我们就可以得到battery的值,也就是默认值,这个默认值的使用场景大多在上述所说的消费者找不到对应的生产者,于是就设置默认值来进行测试啦~~~
const BatteryContext=createContext(60)
总结
不要滥用Context,不要滥用,复用不好,会影响组件的独立性。啦啦啦------小胖子又涨了一点知识。有看见不对的地方,麻烦告诉我一下哦~谢谢啦~嘻嘻嘻嘻嘻