在react中 组件之间的通信受限制于props,也就是说在react中如果嵌套很多层,那么就要传递很多层。 比如这样:
class Two extends React.Component{ render(){ return (<div> <h1>组件是2</h1> <Three code={this.props.code} /> </div>) } } class Three extends React.Component{ render(){ return (<div> <h1>组件是3,传过来的组件是{this.props.code}</h1> </div>) } } export default class TheOne extends React.Component{ constructor(props){ super(props) this.state={code:1}; } render(){ return (<div> <h1>组件是{this.state.code}</h1> <Two code={this.state.code} /> </div>) } }
如果这样去传递 五层就够受了,以后维护的话也是垃圾代码;
这里就要引入一个概念去解决这个问题----context;
在react中最高级组件内 可以定义 所有子组件的 公共上下文, 也就是大约是全局变量的存在了,这样一次定义,所有的组件都能够享受到这个 对象;从而解决了 react的组件的问题;
因为 context 需要校验数据类型所以需要先下载props的校验包;
cnpm i --save prop-types
首先引入prop-types
import PropTypes from "prop-types"
然后
class Two extends React.Component{ render(){ return (<div> <h1>组件是2</h1> <Three /> </div>) } } class Three extends React.Component{ //必须声明 context的类型 强制要求的 因为在react中认为全局变量的设计是不太好的 static contextTypes={ code:PropTypes.string }; render(){ //现在就可以共享到 上下文传输的内容了; return (<div> <h1>组件是3,传过来的组件是{this.context.code}</h1> </div>) } } export default class TheOne extends React.Component{ //必须声明 要共享的 childContext的类型 强制要求 因为在react中认为全局变量的设计是不太好的 static childContextTypes={ code:PropTypes.string }; constructor(props){ super(props) this.state={code:"1"}; } //设置要上下文的公共内容 ; getChildContext(){ return this.state } render(){ return (<div> <h1>组件是{this.state.code}</h1> <Two/> </div>) } }
这样做就可以 去实现不用 props 也可以 传参 (全局共享参数);
这样做要 在顶级组件里声明
//设置要上下文的公共内容 ; getChildContext(){ return this.state }
//必须声明 要共享的 childContext的类型 强制要求 因为在react中认为全局变量的设计是不太好的 static childContextTypes={ code:PropTypes.string };在子组件里 声明
//必须声明 context的类型 强制要求的 因为在react中认为全局变量的设计是不太好的 static contextTypes={ code:PropTypes.string };
然后就可以在子组件里使用了context了
<h1>组件是3,传过来的组件是{this.context.code}</h1>
无状态组件的方式
//这里无状态组件 第一个参数props,第二个参数是共享的上下文; function func(props,context) { //组件的内容 }
下面来 实现一下 react-redux里的provider标签
export default class Provider extends React.Component{ //必须声明 要共享的 childContext的类型是对象 强制要求 static childContextTypes={ store:PropTypes.object }; //这个就是类似于无状态组件的 传参 第一个参数是props,第二个参数是上下文 constructor(props,context){ super(props,context); //定义store, 把 传入的props的store 定义为 要共享上下文的store; this.state={ store:props.store } } // 输出 共享的store getChildContext(){ return this.state } render(){ // 输出 所有的子元素, react中的所有子元素就是 this.props.children return this.props.children } }
这样就完成了react-redux里的Provider