react中的context的基础用法

context提供了一种数据共享的机制,里面有两个关键概念——provider,consumer,下面做一些key features描述。

参考网址:https://react.docschina.org/docs/context.html#reactcreatecontext

consumer:

数据消费者,消费来自己向上回溯过程中,离自己最近的provider提供的数据。

consumer接收一个函数作为子节点,函数返回一个react节点;函数可以消费来自context的值(即最近provider提供的数据)进行内部JSX语法渲染。

provider:

数据提供者,一个provider下的所有消费者都可以消费来自该provider的数据。

provider接收一个value属性,这个属性讲被provider提供给其consumer子节点。

一个provider可对应多个consumer。

生成一对{ provider, consumer}

 

基本上关于Context相关的主要特性都介绍完了,一个完整的demo如下:

theme-context.js

export const themes = {
  light: {
    foreground: '#ffffff',
    background: '#222222',
  },
  dark: {
    foreground: '#000000',
    background: '#eeeeee',
  },
};
export const ThemeContext = React.createContext( 
  themes.light //默认值
  );

themed-button.js

import React from 'react';
import {themes,ThemeContext} from './theme-context';
class ThemeCircle extends React.Component{
  render(){
    return (<ThemeContext.Consumer>
      { theme => (<div
        style={{
          width:"60px",
          height:"60px",
          borderRadius:"30px",
          backgroundColor: theme.background}}>
        {/* Circle */}
        </div>) }
    </ThemeContext.Consumer>
    );
  }
}
class ThemedButton extends React.Component{
  constructor( props ){
    super(props);
  }
  render(){
    return (<ThemeContext.Consumer>
      { theme => (<button
        onClick = {this.props.changeTheme}
        {...this.props}
        style={{
          backgroundColor:theme.background,
          color:theme.foreground,
          width:"100px",
          height:"45px",
          fontSize:"14px",
          borderRadius:"5px",
          border:"none"}}
      />) }
    </ThemeContext.Consumer>);
  }
}
// class ToolBar extends React.Component{//一个用到ThemedButton的中间件
//   constructor( props ){
//     super(props);
//   }
//   render(){//以此种方式直接触发父级事件?
//     return (<ThemedButton onClick={this.props.changeTheme}>
//       Change Theme
//     </ThemedButton>);
//   }
// }
class CustomizedApp extends React.Component{
  constructor( props ){
    super(props);
    this.state = {
      theme: themes.light
    };
    this.handleChangeTheme = this.handleChangeTheme.bind( this );
  }
  handleChangeTheme(){
    //必须有一个机制可以修改provider的value,以引起订阅者consumer的变更
    this.setState( state => ({
      theme: state.theme === themes.light?themes.dark:themes.light
    }) );
  }
  render(){
    return (<div>
      <ThemeContext.Provider value={this.state.theme}>
        {/* <ToolBar changeTheme={this.handleChangeTheme} /> */}
        <ThemedButton changeTheme={this.handleChangeTheme}>
          Toggle
        </ThemedButton>
        <ThemeCircle />
      </ThemeContext.Provider>
    </div>);
  }
}
export default CustomizedApp;

然后在Router里配置调用“CustomizedApp”组件就可以了。

 路漫漫其修远其,吾将上下而求索——May stars guide your way.

posted @ 2019-04-26 18:32  sophel  阅读(977)  评论(0编辑  收藏  举报