百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

React(9)React Context技术(1)(react ?)

zzlvtu 2024-09-04 23:02 6 浏览

前言

为了让组件之间数据传递更加的方便与快捷,React提供了React Context技术。该技术能够简洁的在组件之间传递数据,不仅能完成父子组件之间数据的传递,也能够在多层次组件之间传递数据。本篇文章将详细地讲解React Context技术并展示该技术的功能案例。
在开始正式讲解之前, 再次强调React Context的功能:
实现组件之间的数据传递


一、React Context的基本用法

要想使用React Context技术,首先要使用React.createContext()方法创建React Context对象,该对象包括两个组件:Provider和Consumer。这两个组件可以使用解构的方式定义出来。代码如下所示。

const {Provider,Consumer} = React.createContext();

1、Provider组件

Provider组件用来提供传递数据的来源,被称为“生产组件”。该组件具备一个value属性,该属性的取值就是要传递的数据,使用格式如下所示。

<Provider value={}></Provider>

当Provider组件的value属性绑定的变量发生变化时,所有的消费组件都会被重新渲染。

2、Consumer组件

Consumer组件用来接收传递过来的数据,被称为“消费组件”。该组件内部是一个箭头函数,函数的参数用来接收生产组件传递过来的数据,使用格式如下所示。

<Consumer>
  {
     para=>{
        return ();
    }
  }
</Consumer>

3、基本使用案例

例1:父组件将其state区中的data数据跨越中间件传递给子组件。

const {Fragment,Component}=React;
const {Provider,Consumer}=React.createContext();
//父组件App
class App extends Component{
  constructor(props){
    super(props);
    this.state={
      data:'小海前端'
    }
  }
  btnClick(){
    this.setState({
      data:'React框架'
    })
  }
  render(){
    return(
      <Fragment>
        <Provider value={this.state.data}>
          <button onClick={()=>this.btnClick()}>更改数据</button>
          <p>父组件的数据:{this.state.data}</p>
          <Middle></Middle>
        </Provider>
      </Fragment>
    )
  }
}
//中间件
function Middle(props){
  return (
    <Child></Child>
  )
}
//子组件Child
class Child extends Component{
  render(){
    return(
      <Consumer>
        {
          para=>{
            return (
              <Fragment>
                <p>子组件的数据:{para}</p>
              </Fragment>
            )
          }
        }
      </Consumer>
    )
  }
}
ReactDOM.render(
  <App></App>,
  document.querySelector('#app')
);

在这个例子中,数据的传递顺序是:父组件App -> 中间件Middle -> 子组件Child。在此中间件也可以不设置,本例中只是为了说明,通过React Context可以跨组件进行数据传递。

二、滑动门案例

例2:制作一个如下图所示的滑动门效果。该案例将分为两个组件,父组件App用来实现整个案例的布局和左侧数据的遍历。子组件Detail用来实现右侧具体商品信息的展示。

首先,想通过数据模拟四款电子商品的品牌、大小、颜色、单价等数据。

const phone=[
  {
    brand:'iPhone 12',
    size:256,
    color:'深空灰',
    price:5800
  },
  {
    brand:'iPad Air 4',
    size:512,
    color:'时尚绿',
    price:4499
  },
  {
    brand:'iPad Pro',
    size:512,
    color:'土豪金',
    price:7899
},
 {
    brand:'iPad Mini',
    size:64,
    color:'黑色',
    price:2799
  }
];

1、父组件App的实现

在父组件的state区设置一个名为pro的数据,该数据存储以下两个信息。

  • isOk:表示用户是否鼠标经过了某个左侧商品项。默认情况下没有经过,所以初值为false。
  • detail:表示用户鼠标经过左侧商品时,该商品的详情信息。默认情况下是空对象。

同时这个pro数据也是父组件App要向子组件Detail传递的数据,也就是生产组件中value属性要绑定的变量。当鼠标经过任意商品项时,改变pro的值,这样接收生产组件的消费组件也会重新渲染。

class App extends Component {
  constructor(props){
    super(props);
    this.state={
      pro:{
        isOk:false,
        detail:{
          brand:'',
          size:'',
          color:'',
          price:''
        }
      }
    }
  }
  getInfo(index){
    this.setState({
      pro:{
        isOk:true,
        detail:phone[index]
      }
    })
  }
  render(){
    return (
      <Fragment>
        <Provider value={this.state.pro}>
          <div className="phone">
            <div className="left">
              <ul>
                {
                  phone.map((item,index)=>{
                    return (
                      <li onMouseOver={()=>this.getInfo(index)} key={index}>{item.brand}</li>
                    )
                  })
                }
              </ul>
            </div>
            <div className="right">
              <Detail></Detail>
            </div>
          </div>
        </Provider>
      </Fragment>
    )
  }
}

2、子组件Detail的实现

子组件中设置一个消费组件,其中箭头函数的参数product就是接收生产组件传递过来的数据。通过该数据中的isOk来判断鼠标是否经过了某个商品项。如果isOk取值为true,则将最终的商品细节显示在页面中,否则显示空字符串。这样可以保证项目一运行,右侧的商品细节中不会显示任意一款商品的信息。

class Detail extends Component {
  render(){
    return (
      <Consumer>
        {
          product=>{
            return (
              <Fragment>
                <h4>请从左侧选择一款商品:</h4>
                {
                  product.isOk
                  ?
                  <div>
                    <p>品牌:{product.detail.brand}</p>
                    <p>大小:{product.detail.size}</p>
                    <p>颜色:{product.detail.color}</p>
                    <p>单价:{product.detail.price}</p>
                  </div>
                  :
                  ''
                }
              </Fragment>
            )
          }
        }
      </Consumer>
    )
  }
}

三、多Context数据的使用

若需要使用多个Context数据,则必须为React.createContext()方法生成的变量起一个名字,而不能直接对其进行解构的。 例如要设置两个不同的Context数据,代码如下所示。

const schoolContext = React.createContext();
const studentContext = React.createContext();

这时,生产组件Provider的使用方法如下所示。

<schoolContext.Provider value={}></schoolContext.Provider>
<studentContext.Provider value={}></studentContext.Provider>

消费组件Consumer的使用方法如下所示。

<schoolContext.Consumer></schoolContext.Consumer>
<studentContext.Consumer></stucentContext.Consumer>

例3:用多Context的方法改造例2中的滑动门效果。

在例2中,我们为了传递鼠标是否经过某商品项和鼠标经过商品项是的商品细节,将这两部分信息都合成在了一个名为pro的state数据中。有了多Context技术,我们就可以将这两部分的信息分成两个不同的Context数据来进行传递。

const {Fragment,Component}=React;
//定义两个Context数据
const isOkContext=React.createContext();
const productContext=React.createContext();
//父组件App
class App extends Component {
  constructor(props){
    super(props);
    this.state={
      isOk:false,
      pro:{
        brand:'',
        size:'',
        color:'',
        price:''
      }
    }
  }
  getInfo(index){
    this.setState({
      isOk:true,
      pro:phone[index]
    })
  }
  render(){
    return (
      <Fragment>
        <isOkContext.Provider value={this.state.isOk}>
          <productContext.Provider value={this.state.pro}>
            <div className="phone">
              <div className="left">
                <ul>
                  {
                    phone.map((item,index)=>{
                      return (
                        <li onMouseOver={()=>this.getInfo(index)} key={index}>{item.brand}</li>
                      )
                    })
                  }
                </ul>
              </div>
              <div className="right">
                <Detail></Detail>
              </div>
            </div>
          </productContext.Provider>
        </isOkContext.Provider>
      </Fragment>
    )
  }
}
//子组件:包括右侧具体一组数据的显示
class Detail extends Component {
  render(){
    return (
      <isOkContext.Consumer>
        {
          isOk=>(
            <productContext.Consumer>
              {
                product=>{
                  return (
                    <Fragment>
                      <h4>请从左侧选择一款商品:</h4>
                      {
                        isOk
                        ?
                        <div>
                          <p>品牌:{product.brand}</p>
                          <p>大小:{product.size}</p>
                          <p>颜色:{product.color}</p>
                          <p>单价:{product.price}</p>
                        </div>
                        :
                        ''
                      }
                    </Fragment>
                  )
                }
              }
            </productContext.Consumer>
          )
        }
      </isOkContext.Consumer>
    )
  }
}
ReactDOM.render(
  <App></App>,
  document.querySelector('#app')
);

总结

本文是React系列教程的第九篇文章,主要为大家讲解了React Context的基础用法。该技术提供了生产组件<Provider>和消费组件<Consumer>的概念,实现了更加方便的在组件之间传递数据的方式。本次讲解的是React Context技术的基本用法,下一篇文章会讲解React Context在修改页面主题功能上的应用,以及ContextType技术的简化写法,并为大家演示带有默认值的Context是如何使用的。

关于作者

小海前端,具有18年Web项目开发和前后台培训经验,在前端领域著有较为系统的培训教材,对Vue.js、微信小程序开发、uniApp、React等全栈开发领域都有较为深的造诣。入住今日头条,希望能够更多地结识Web开发领域的同仁,将Web开发大力地进行普及。同时也愿意与大家进行深入的技术研讨和商业合作。

相关推荐

什么是DPDK?DPDK的原理及学习学习路线总结

一、什么是DPDK  对于用户来说,它可能是一个性能出色的包数据处理加速软件库;对于开发者来说,它可能是一个实践包处理新想法的创新工场;对于性能调优者来说,它可能又是一个绝佳的成果分享平台。 ...

每天进步一点:两分钟解决kvm下windows虚拟机鼠标不跟随

跟随昨天文章做测试的朋友们应该和我一样遇到了vnc连接windows鼠标不跟随的问题,经过一番查找有两种解决办法:1.编辑配置文件命令virshedittest或者直接vi/etc/libvir...

PC虚拟化主流:KVM、XEN、OpenVZ详解

目前,PC的虚拟化逐渐成为互联网发展的大趋势,我们知道,KVM、XEN、OpenVZ是虚拟化的三种方式,今天我们就来探讨这三种虚拟化的优势和劣势。1、pc虚拟化——KVMKVM是完整的硬件虚拟化,可在...

Windows上使用QEMU创建aarch64(ARM64)虚拟机

前言随着国产化的推进,现在采用ARM、MIPS的机器越来越多,作为开发、运维人员要调测软件总不能每种架构的机器都去买一台吧?主要像博主这样的穷B,实在也是承受不起。。需要的工具...

高度致敬Windows!开源优麒麟20.04 LTS发布:支持5年

优麒麟团队宣布,优麒麟(UbuntuKylin)开源操作系统20.04LTS正式版已经发布,代号FocalFossa,全球同步发布的还有Ubuntu20.04、Lubuntu20.04、Xub...

极空间虚拟机上线了,一学就会!小白保姆级使用教程

友情提示本文涉及内容较多,篇幅在4500字左右,为了对小白用户更加友好,图片示例多达60张。整个文章部分为三个阶段,准备-初探-实战。其中实战部分包含Windows系统,ikuai软路由系统,iSto...

Windows Subsystem for Linux现以应用形式上架Microsoft Store

微软今天宣布WindowsSubsystemforLinux(WSL)作为一款应用上架Windows11端的MicrosoftStore。也就是说,现在WSL以应用的方式通过...

Windows Server 2019 Core 虚拟机系统镜像制作

WindowsServer2019Core简介WindowsServer2019是微软于2018年11月13日发布的新一代WindowsServer服务器操作系统,基于Win10180...

微软商店中的WSL预览版现已可用!Windows 11用户狂喜

...

在NAS上安装Win10,24小时待命的云电脑达成√

#头条创作挑战赛#引子...

免费开源虚拟机VirtualBox 7.0.12发布:修复TPM和黑屏问题

IT之家10月18日消息,甲骨文近日发布了VirtualBox7.0.12维护版本更新,重点修复此前版本中用户反馈和官方发现的BUG,改善了对LinuxKernel6.4/6.5...

KVM Cloud 虚拟机管理系统安装部署

KVMCloud介绍KVMCloud是一款基于KVM实现的适用于小微企业的虚拟机管理系统,支持如下功能:基于KVM的VM基础功能(创建、启动、停止、重装、webVNC等功能)使用NFS作为磁盘...

个人KVM 虚拟化学习笔记(kvm虚拟化管理平台)

一、KVM原理二、KVM基础功能2.1CPU2.2内存2.3存储2.4网络三、KVM高级功能...

kvm虚拟化之ESXi到KVM之v2v迁移(esxi虚拟机迁移到另一个esxi)

1.ESXi到KVM之v2v情况说明(1).配置任务列表:1)VMwareESXi虚拟平台下linux系统迁移到KVM虚拟平台。2)VMwareESXi虚拟平台下windows系统迁移到KVM虚拟平台...

unraid下虚拟机安装Windows(vmware安装unraid)

unraid下虚拟机安装Windows使用unraid也有一段时间了,主要是做数据备份,以及docker容器的安装测试,今天有空测试一下VMS虚拟机的使用,用在unraid上安装windows7操作系...