context方便祖先组件向后代组件传值
有些的时候需要这么处理,但是项目中不能过多的使用,会让项目变得复杂难化
下面是一个换肤的例子介绍context的使用
目录如下
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;
}
}
页面样式如下图
- 点击red,orange,pueple按钮,效果分别如下