第十节-Context上下文

121 阅读1分钟

context方便祖先组件向后代组件传值

有些的时候需要这么处理,但是项目中不能过多的使用,会让项目变得复杂难化

下面是一个换肤的例子介绍context的使用

目录如下

image.png

context.js 配置文件

  • 通过React.createContext来定义一个变量
import React from "react";
const ThemeContext = React.createContext('black');

export {
  ThemeContext
}

App.jsx

import React, { Component } from 'react'
import Main from './Main.jsx'
/**
 * ThemeContext
 * Provider 供应方
 * Comsumer 消费方(使用方)
 */
import { ThemeContext } from './context'
export default class App extends Component {
  state = {
    theme: 'black'
  }
  //=> 切换主题方法
  themeChange(theme) {
    this.setState({
      theme
    })
  }
  render() {
    return (
       //=> 把theme的值传递到后代组件中去
      <ThemeContext.Provider value={ this.state.theme }>
        <Main themeChange={ this.themeChange.bind(this) }></Main>
      </ThemeContext.Provider> 
    )
  }
}

Main.jsx

import React, { Component } from 'react'
import ButtonNav from './buttonNav/ButtonNav'
import Header from './header/Header'

export default class Main extends Component {
  state = {
    navData: [
      "第①",
      "第②",
      "第③",
      "第④"
    ]
  }
  render() {
    return (
      <>
        <Header>这是标题</Header>
        <div style={{marginTop: 88 + 'px'}}>
          <button onClick={() => this.props.themeChange('black')}>Black</button>
          <button onClick={() => this.props.themeChange('red')}>Red</button>
          <button onClick={() => this.props.themeChange('orange')}>Orange</button>
          <button onClick={() => this.props.themeChange('purple')}>Purple</button>
        </div>
        <ButtonNav
          data={this.state.navData}
        ></ButtonNav>
      </>
    )
  }
}

header 组件

//=> Header.jsx
import React, { Component } from 'react'
import './Header.scss'

import {ThemeContext} from '../context'
export default class Header extends Component {
  render() {
    return (
      <ThemeContext.Consumer>
        {
          (theme) => <header className={ `header ${theme}` }>{ this.props.children }</header>
        }
        
      </ThemeContext.Consumer>
    )
  }
}
//=> Header.scss
.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 44px;
  background-color: #000;
  color: #fff;

  text-align: center;
  line-height: 44px;

  &.black {
    background-color: #000;
    color: #fff;
  }

  &.red {
    background-color: red;
    color: #fff;
  }

  &.orange {
    background-color: orange;
    color: #000;
  }

  &.purple {
    background-color: purple;
    color: #fff;
  }
}

buttonNav

  • ButtonNav组件
import React, { Component } from 'react'
import './ButtonNav.scss'
import NavItem from './NavItem'
export default class ButtonNav extends Component {
  render() {
    return (
      <div className='bottom-nav'>
        {
          this.props.data.map((item, index) => {
            return (
              <NavItem
                item={item}
                index={index}
                key={index}
              ></NavItem>
            )
          })
        }
      </div>
    )
  }
}
  • NavItem组件
import React, { Component } from 'react'
import { ThemeContext } from '../context'
import './NavItem.scss'
export default class NavItem extends Component {
  render() {
    const {index, item} = this.props
    return (
      <ThemeContext.Consumer>
        {
          (theme) => 
          <div className={ !index ? `item active-${theme}` : 'item'}>{ item }</div>
        }
      </ThemeContext.Consumer>
      
    )
  }
}
.bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 44px;
  background-color: #efefef;
}

.item {
  float: left;
  width: 25%;
  line-height: 44px;
  height: 100%;
  text-align: center;
  font-size: 14px;
  color: #999;

  &.active-black {
    color: #000;
  }
  &.active-red {
    color: red;
  }
  &.active-orange {
    color: orange;
  }
  &.active-purple {
    color: purple;
  }
}

页面样式如下图

image.png

  • 点击red,orange,pueple按钮,效果分别如下

image.png