React 基础学习笔记【四】

Context 共享数据

为避免太多层数据没必要的props传递,16.3版本设计了context组件数据共享

【案例】点击不同主题按钮切换下方区域样式

1.在src下新建theme-context.js组件,用于存放共享数据(中转站)

theme-context.js组件代码如下,定义一个Context将它导出,供子组件导入

import React from 'react'

const ThemeContext =React.createContext()



export default ThemeContext复制代码

2.父组件引入import ThemeContext from './theme-context'

3.在父组件里,将要传值的视图板块,用<ThemeContext>标签包裹起来,

其中两个a标签是要点击变换的按钮,

render() {
  return (
      <ThemeContext.Provider>
    <div className="App">
        <a href="#theme-switcher"
           className="btn btn-light"
        >浅色主题</a>
        <a href="#theme-switcher"
           className="btn btn-secondary"
        >深色主题</a>
    </div>
      </ThemeContext.Provider>
  );复制代码

4.在父组件里,定义共享数据themes,有两条数据light和dark,数据里分别是css样式

const themes = {
  light:{
    className:'btn btn-primary',
      bgColor:'#eeeeee',
      color:'#000'
  },
    dark:{
    className: 'btn btn-light',
        bgColor: '#222222',
        color:'#fff'
    },
}复制代码

5.在components文件夹里新建ThemeBar.js组件,用于展示样式变换

首先在此组件引入import ThemeContext from '../theme-context'

将组件要接收共享数据的模块用<ThemeContext>标签包裹,并.Consumer导入

return(
    <ThemeContext.Consumer>
        {
            theme =>{
                //console.log(theme)
                return(
                   <div
                   className="alert mt-5"
                   }}
                   >
                       样式区域
                       <button>
                            样式按钮
                       </button>
                   </div>
                )
            }
        }
    </ThemeContext.Consumer>
)复制代码

6.在父组件的标签里设置value将themes数据导出,

给a标签添加点击事件changTheme,参数分别为light和dark

  <ThemeContext.Provider value={themes[this.state.theme]}>
  <div className="App">
      <a href="#theme-switcher"
         className="btn btn-light"
        onClick={()=>{this.changeTheme('light')}}
      >浅色主题</a>
      <a href="#theme-switcher"
         className="btn btn-secondary"
         onClick={()=>{this.changeTheme('dark')}}
      >深色主题</a>
    <ThemeBar/>
  </div>
    </ThemeContext.Provider>
);复制代码

7.在state中设置theme默认为light样式

constructor(props){
  super(props)
    this.state = {
        theme:"light"
    }
}复制代码

8.给changTheme事件绑定this

constructor(props){
  super(props)
    this.state = {
        theme:"light"
    }
    this.changeTheme = this.changeTheme.bind(this)
}复制代码

9.定义changTheme事件,点击哪个a切换至相应参数下的数据

changeTheme(theme){
  this.setState({
      theme,
  })
}复制代码

10.在展示样式的组件中,给div绑定style,获取父元素theme数据下的bgColor等数据

return(
    <ThemeContext.Consumer>
        {
            theme =>{
                //console.log(theme)
                return(
                   <div
                   className="alert mt-5"
                   style={{ backgroundColor:theme.bgColor,
                   color:theme.color,
                   }}
                   >
                       样式区域
                       <button className={theme.className}>
                            样式按钮
                       </button>
                   </div>
                )
            }
        }
    </ThemeContext.Consumer>
)复制代码

就做到了一个视图展示层  共享同一份  不同元素的数据

点击切换组件  修改同一个视图模板下的不同css样式

所有代码:

App.js下:

import React, { Component } from 'react';
import './App.css';
import ThemeBar from './components/ThemeBar'
import ThemeContext from './theme-context'

const themes = {
  light:{
    className:'btn btn-primary',
      bgColor:'#eeeeee',
      color:'#000'
  },
    dark:{
    className: 'btn btn-light',
        bgColor: '#222222',
        color:'#fff'
    },
}

class App extends Component {
  constructor(props){
    super(props)
      this.state = {
          theme:"light"
      }
      this.changeTheme = this.changeTheme.bind(this)
  }

    changeTheme(theme){
      this.setState({
          theme,
      })
    }

  render() {
    return (
        <ThemeContext.Provider value={themes[this.state.theme]}>
      <div className="App">
          <a href="#theme-switcher"
             className="btn btn-light"
            onClick={()=>{this.changeTheme('light')}}
          >浅色主题</a>
          <a href="#theme-switcher"
             className="btn btn-secondary"
             onClick={()=>{this.changeTheme('dark')}}
          >深色主题</a>
        <ThemeBar/>
      </div>
        </ThemeContext.Provider>
    );
  }
}

export default App;
复制代码

ThemeBar.js下:展示样式变换组件

import React from 'react'
import ThemeContext from '../theme-context'

const ThemeBar = ()=>{
    return(
        <ThemeContext.Consumer>
            {
                theme =>{
                    //console.log(theme)
                    return(
                       <div
                       className="alert mt-5"
                       style={{ backgroundColor:theme.bgColor,
                       color:theme.color,
                       }}
                       >
                           样式区域
                           <button className={theme.className}>
                                样式按钮
                           </button>
                       </div>
                    )
                }
            }
        </ThemeContext.Consumer>
    )
}

export default ThemeBar复制代码

theme-context.js下:

import React from 'react'

const ThemeContext =React.createContext()



export default ThemeContext复制代码

最终样式:默认为light主题,点击对应按钮切换对应主题

猜你喜欢

转载自blog.csdn.net/weixin_38404899/article/details/87475494