React context基本用法

摘要:
React的context就是一个全局变量,可以从根组件跨级别在React的组件中传递。Reactcontext的API有两个版本,React16.x之前的是老版本的context,之后的是新版本的context。contextTypes没有定义,context将是一个空对象。themes.light:themes.dark,}));};this.state={theme:themes.light,toggle:this.toggle,};}render(){return;}}//中间组件functionContent(){return;}//接收组件functionButton(){return;}详细用法可以参考官方文档:https://react.docschina.org/docs/context.html#reactcreatecontext3.context在如下的生命周期钩子中可以使用constructorcomponentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdate4.在无状态组件中可以通过参数传入functionD{return;}D.contextTypes={user:React.PropTypes.object.isRequired}5.Reactcontext的局限性1.在组件树中,如果中间某一个组件ShouldComponentUpdatereturningfalse了,会阻碍context的正常传值,导致子组件无法获取更新。

React的context就是一个全局变量,可以从根组件跨级别在React的组件中传递。React context的API有两个版本,React16.x之前的是
老版本的context,之后的是新版本的context。

1.老版本的context

getChildContext 根组件中声明,一个函数,返回一个对象,就是context
childContextTypes 根组件中声明,指定context的结构类型,如不指定,会产生错误
contextTypes 子孙组件中声明,指定要接收的context的结构类型,可以只是context的一部分结构。contextTypes 没有定义,context将是一个空对象。
this.context 在子孙组件中通过此来获取上下文
(注:从React v15.5开始 ,React.PropTypes 助手函数已被弃用,可使用 prop-types 库 来定义contextTypes)

举例如下:

//根组件
class MessageList extends React.Component {
  getChildContext() {
    return {color: "purple",text: "item text"};
  }
  render() {
    const children = this.props.messages.map((message) =>
      <Message text={message.text} />
);
    return <div>{children}</div>;
}
}
MessageList.childContextTypes ={
  color: React.PropTypes.string
  text: React.PropTypes.string
};
//中间组件
class Message extends React.Component {
  render() {
    return(
      <div>
        <MessageItem />
        <Button>Delete</Button>
      </div>
);
  }
}
//孙组件(接收组件)
class MessageItem extends React.Component {
  render() {
    return(
      <div>
        {this.context.text}
      </div>
);
  }
}
MessageItem.contextTypes ={
  text: React.PropTypes.string
};
class Button extends React.Component {
  render() {
    return(
      <button style={{background: this.context.color}}>
        {this.props.children}
      </button>
);
  }
}
Button.contextTypes ={
  color: React.PropTypes.string
};

2.新版本的context

新版本的React context使用了Provider和Customer模式,和react-redux的模式非常像。在顶层的Provider中传入value,
在子孙级的Consumer中获取该值,并且能够传递函数,用来修改context,如下代码所示:

//创建Context组件
const ThemeContext =React.createContext({
  theme: 'dark',
  toggle: () => {}, //向上下文设定一个回调方法
});
//运行APP
class App extends React.Component {
  constructor(props) {
    super(props);
    this.toggle = () => { //设定toggle方法,会作为context参数传递
      this.setState(state =>({
        theme:
          state.theme ===themes.dark
            ?themes.light
            : themes.dark,
      }));
    };
    this.state ={
      theme: themes.light,
      toggle: this.toggle,
    };
  }
  render() {
    return(
      <ThemeContext.Provider value={this.state}> //state包含了toggle方法
        <Content />
      </ThemeContext.Provider>
);
  }
}
//中间组件
functionContent() {
  return(
    <div>
      <Button />
    </div>
);
}
//接收组件
functionButton() {
  return(
    <ThemeContext.Consumer>
      {({theme, toggle}) =>(
        <button
          onClick={toggle} //调用回调
          style={{backgroundColor: theme}}>
          Toggle Theme
        </button>
)}
    </ThemeContext.Consumer>
);
}

详细用法可以参考官方文档:https://react.docschina.org/docs/context.html#reactcreatecontext

3. context在如下的生命周期钩子中可以使用

constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)

4. 在无状态组件中可以通过参数传入

functionD(props, context) {
  return(
    <div>{this.context.user.name}</div>
);
}
D.contextTypes ={
  user: React.PropTypes.object.isRequired
}

5. React context的局限性

1. 在组件树中,如果中间某一个组件 ShouldComponentUpdate returning false 了,会阻碍 context 的正常传值,导致子组件无法获取更新。
2. 组件本身 extends React.PureComponent 也会阻碍 context 的更新。

注意点:

1. Context 应该是唯一不可变的
2. 组件只在初始化的时候去获取 Context

参考:https://www.tuicool.com/articles/nUryimf
https://segmentfault.com/a/1190000012575622

免责声明:文章转载自《React context基本用法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇springMVC-错误消息的显示和国际化python2.7实现websocket服务器,可以在web实时显示远程服务器日志下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

React全家桶

React全家桶入门Demo http://react-china.org/t/react-demo/22800 最具性价比的一套就看react_home吧,从react出来就有的开源项目,react脚手架 https://github.com/aiyuekuang/react_home...

react antd form 自定义表单验证validator 需要注意的细节,否则会无法触发表单提交。

1、每一个if判断后,都需要加入callback(),否则会阻塞表单的提交。 validateNoChinese = (_, value, callback) => { const reg = /^d+$|^d*.d+$/g; const startValue = value?.split('.') if(!value){...

图片轮播插件-carouFredSel

carouFredSel图片轮播插件基于Jquery,比较常规的轮播插件,支持滚轮及键盘左右按键,加入其它插件可实现更加复杂的特效。 主页地址:http://caroufredsel.dev7studios.com/ 例子: html: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio...

Neo4J图库的基础介绍(二)-图库开发应用

我们接着Neo4J图库的基础介绍(一)继续介绍Neo4J图库。 JAX-RS是一个用于构建REST资源的Java API,可以使用JAX-RS注解装饰每一个扩展类,从而让服务器处理对应的http请求,附加注解可以用来控制请求和响应的格式,http头和URI模板的格式。 下面看一个服务器扩展实现的示例,允许客户端请求社交网络的两个成员之间的距离 @Pa...

swift3.0 CoreGraphics绘图-实现画板

swift3.0对绘图的API进行了优化,看起来更swift了。 看下UI的构造。设置画笔粗细、清空面板和保存到本地 下面直接看画板文件 这里我做的比较复杂,记录触摸到的每个点,再连成路径,其实直接用可变路径CGMutablePath可变路径就可以实现。 成员变量 public var lineWidth:CGFloat = 1 file...

Canvas 全局不透明度和全局图像重叠设置

全局不透明度 globalAlpha globalAlpha = 1 (Default) var canvas = document.getElementById('canvas') canvas.width = 1200; canvas.height = 800; var context = canvas.getContext(...