前言
关于组件化开发规范,希望申明一个原则——能不用Redux就不要使用Redux解决。在普通开发中遇到父子组件通信时,需要考虑通过传统Props和子组件的回调来解决基本通信,今天主要整理关于组件通信的解决方案
父组件向子组件通信
父组件通过向子组件传递 props,子组件得到 props 后进行相应的处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ..... import Sub from 'Sub.js'; // 子组件 class Container extends React.Component{ constructor(){ super(); } render(){ return ( <Sub title="评论列表" // 通过属性传递 name={"xx"} /> ); } }
|
子组件向父组件通信
利用回调函数,可以实现子组件向父组件通信:
父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,便可以向父组件通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <Container.js> ..... import Sub from 'Sub.js'; class Container extends React.Component{ constructor(){ super(); } getChildMsg(msg){ console.log("子组件给父组件通信内容: "+msg); } render(){ return ( <Sub title="评论列表" callback={this.getChildMsg.bind(this)} // 将回调函数传给子组件 /> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <Sub.js> ..... class Sub extends React.Component{ constructor(props){ super(props); this.onOk=this.onOk.bind(this); } onOk(){ this.props.callback("sub"); // 回调函数 } render(){ return ( <div> <button onClick={this.onOk}></button> </div> ); } } exprot default Sub;
|
跨级组件之间的通信
所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:
1、使用 context 对象
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 1.声明自己支持的context,并且提供context中属性的PropType. 声明: static childContextTypes={ name: PropTypes.string, // 需要传入给子组件的参数 getData: PropTypes.func, arr: PropTypes.array } 2. 提供一个getChildContext函数,返回一个初始化的context对象 返回context对象: getChildContext(){ return{ name: this.state.name, arr : this.props.array, getData: this.getData.bind(this) } } 3. 回调函数 getData(data){ console.log(data);// data 为子组件传给父组件的回调 }
|
子组件:
1 2 3 4 5 6 7 8 9
| 1. 声明自己需要使用的context static contextTypes={ name: PropTypes.string, getData: PropTypes.func } 2. 使用context var name = this.context.name; var str = "把这个值传递给父级"; this.context.getData(str);
|
注意事项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 1. 在组件中如果有constructor,在构造函数中,应该将context传入 constructor(props, context){ super(props, context); } 2. 改变context对象 3. context在无状态组件中的用法 const Sub =(props, context)=>{ var name = context.name; context.getData("回调传参"); retrun( <div>....</div> ); } Sub.contextTypes={ name: PropTypes.string, getData: PropTypes.func 4. context 在生命周期中的用法 constructor(props, context) componentWillReceiveProps(nextProps, nextContext) shouldComponentUpdate(nextProps, nextState, nextContext) componentWillUpdate(nextProps, nextState, nextContext) componentDidUpdate(prevProps, prevState, prevContext) 5. 根据react的组件层级,一个组件可以有多个父级,可以同时声明在不通父级中要使用的context
|
2、中间组件层层传递 props
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| App.js render(){ return( <Sub name="test" sendData={this.sendData.bind(this)} /> ); }; Sub.js render(){ return( <SubSub name={this.props.name} sendData={this.props.sendData} /> ); }; SubSub.js .... var name = this.props.name; this.props.sendData("App回调"); ...
|
非嵌套组件间通信
1、同context
2、Redux!!!!!!!