React(10)React Context技术(2)


前言

承接上一篇关于React Context技术的文章。React Context技术在页面主题修改应用上提供了较好的方法,同时React还提供了ContextType技术,用于实现对Context技术进行简化书写。本篇文章对这两个概念进行讲解,最后再讲解Context默认值的使用方法。

在开始正式讲解之前, 再次强调React Context的功能:实现组件之间的数据传递。


一、案例:更改页面的主题

1、案例要求

页面中有两个超级链接,用于控制页面中内容的主题颜色。两个超级链接分别是“浅色主题”和“深色主题”。为了掩饰主题的更改,在页面中还设置了一个div容器,深浅色主题对应该div容器不同的背景颜色。div容器中有文本和一个命令按钮,深浅色主题也对应着文本的不同颜色和按钮的不同样式。案例的最终效果图如下所示。
在这里插入图片描述
在这里插入图片描述

2、案例分析

首先,我们要在所有组件以外预设好两个主题的参数。根据对效果图的观察,两个不同的主题主要对应的是背景颜色、文本颜色、按钮颜色三个组成部分。规划具体的主题参数如下所示。

背景颜色文本颜色按钮颜色样式
浅色模式#dddddd#000000.btn-primary
深色模式#222222#ffffff.btn-danger

在上述表中,为按钮颜色规划的是Bootstrap框架中的两种不同的按钮背景颜色类。如果不使用Bootstrap,也可以在CSS文件中独立书写这两个类,并为这两个类设置不同的外观。

按照上述表中的外观规划,定义一个themes的对象,包含两种主题样式,代码如下所示。

const themes={
  light:{
    className:'btn btn-primary',
    backgroundColor:'#ddd',
    color:'#000'
  },
  dark:{
    className:'btn btn-danger',
    backgroundColor:'#222',
    color:'#fff'
  }
};

3、案例组件划分

其次,我们来为这个案例进行组件划分。很显然,我们可以将其划分为两个组件:

  • 父组件<App />:实现改变主题的超级链接和整个案例的布局。
  • 子组件<Content />:实现案例下方的<div>容器和其内部的文本与按钮。

4、<App />组件的实现

在书写组件<App />时,要先创建Context对象,并解构出生产组件和消费组件。

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

为了能将用户所选的主题传递给子组件,来让子组件改变样式,我们需要在父组件中创建一个state数据,命名为themeData。该数据的默认值为‘light’,表示默认为浅色主题。当用户单击深色主题超级链接时,改变themeData数据的值为‘dark’。同时将这个themeData作为数据传递给子组件。

<App />组件的代码如下所示。

class App extends Component {
  constructor(props){
    super(props);
    this.state={
      themeData:'light'
    }
  }
  changeTheme(data){
    this.setState({
      themeData:data
    })
  }
  render(){
    return (
      <Provider value={this.state.themeData}>
        <div className="theme">
          <a href="#" onClick={()=>this.changeTheme('dark')}>深色主体</a>
          <a href="#" onClick={()=>this.changeTheme('light')}>浅色主题</a>
        </div>
        <Content></Content>
      </Provider>
    )
  }
}

5、<Content />组件的实现

该组件作为<App />组件的消费组件,要是用<Consumer>组件接收<App />组件传来的数据。即接收的数据为一个字符串:‘light’或‘dark’。然后再从表示主题的themes对象中,寻找对应字符串成员的各种样式取值。

<Content />组件的代码如下所示。

class Content extends Component {
  render(){
    return (
      <Consumer>
        {
          data=>{
            return (
              <div className="content" style={{backgroundColor:themes[data].backgroundColor,color:themes[data].color}}>
                欢迎使用Context技术 <button className={themes[data].className}>确定</button>
              </div>
            )
          }
        }      
      </Consumer>
    )
  }
}

二、ContextType技术

ContextType技术是React设定的Context技术的简写形式,使用ContextType技术可以省略书写<Consumer>标记对。
ContextType的书写格式有如下规定:

  • 必须为创建的Context对象设置一个对象名,且无需解构出Consumer。
  • 在消费组件的render()函数外部,要定义一个静态变量,并赋值为创建的Context对象名。
  • 在消费组件的render()函数内部,return语句之前,使用this.context来接收生产组件传递过来的参数。

把上述案例整体改写为ContextType技术,其书写格式如下所示。

const themeContext=React.createContext();
const {Provider} = themeContext;
class Content extends Component{
  static contextType = themeContext;
  render(){
    const para=this.context;    //para就是接收到的生产组件传来的数据
    return (
      <div className="content" style={{backgroundColor:themes[para].backgroundColor,color:themes[para].color}}>
        欢迎使用Context技术 <button className={themes[para].className}>确定</button>
      </div>
    )
  }
}

三、Context的默认值

在利用React.createContext()方法创建Context对象时,该方法是具备参数的,该参数是Context的默认值。格式如下所示。

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

若想让该默认值生效,则生产组件无需使用进行包裹,这样消费组件只能接受到defaultValue传递过来的数据。即没有被<Provider>包裹的组件只能获取Context的defaultValue,也只能向消费组件传递defaultValue的值。


总结

本文是React系列教程的第十篇文章,在上一讲的基础之上继续讲解了React Context的用法。本篇文章主要包括React Context在修改页面主题功能上的应用,以及ContextType技术的简化写法,并为大家讲解了带有默认值的Context是如何使用的。

第一讲 初识React框架

第二讲 认识JSX语法格式

第三讲 React组件

第四讲 React 父子组件之间的通信

第五讲 React兄弟组件之间的通信

第六讲 React受控组件的使用

第七讲 React非受控组件的使用

第八讲 React组件的生命周期

第九讲 React Context技术(1)

关于作者

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小海前端

原创不易,量力支持,感谢打赏。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值