React 通信:
父组件传给子组件:
看例子前,先说一个通俗的理解,就是子组件在父组件中,自己的标签内定义一个键值对,值可以是父组件的参数,然后在子组件中,this.props.属性名字,就可以获取到这个值
//这个是父组件
export default class App extends Component{
render(){
return(
<div>
<Sub title = "今年过节不收礼" />
</div>
)
}
}
//这里是子组件
const Sub = (props) => {
return(
<h1>
{ props.title }
</h1>
)
}
小结:在父组件中,子组件可以在自己的标签中,键值对的形式添加待传递的值,然后子组件内部,使用this.props.属性名字获取,
子组件向父组件传值
父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,便可以向父组件通信 ,有点像jsonp的那种感觉
//父组件
export default class App extends Component{
callback(msg){
console.log(msg);
}
render(){
return(
<div>
<Sub callback = { this.callback.bind(this) } />
</div>
)
}
}
//子组件
const Sub = (props) => {
const cb = (msg) => {
return () => {
props.callback(msg)
}
}
return(
<div>
<button onClick = { cb("我们通信把") }>点击我</button>
</div>
)
}
小结:过程就是父组件将一个回调函数传给子组件,然后子组件调用把要传的值放进函数参数,这个回调函数最终在父组件中执行,然后父组件通过操作argument,获取值
跨级组件通信
跨级组件就是父组件向子组件的子组件传值,当然也可以更深 我们可以一层层的父传子,但是这样有点傻,而且难以维护,所以有了context对象 context 相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。 整体步骤:父组件中定义要传的属性类型,和属性的键值对--->子组件定义要接受的属性类型,和属性的名字,this.context.属性名字取值
// 父组件
export default class App extends Component{
// 父组件声明自己支持 context,并且准备传两个属性,color和callback回调函数
static childContextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
// 父组件提供一个函数,用来返回相应的 context 对象,要传的color和callback回调函数在里面
getChildContext(){
return{
color:"red",
callback:this.callback.bind(this)
}
}
callback(msg){
console.log(msg)
}
render(){
return(
<div>
<Sub></Sub>
</div>
);
}
}
// 子组件
const Sub = (props) =>{
return(
<div>
<SubSub />
</div>
);
}
//最小子组件
export default class SubSub extends Component{
// 子组件声明自己需要使用 context,并且定义需要属性的名字和类型
static contextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
render(){
// 直接this.context.属性名字使用
const style = { color:this.context.color }
const cb = (msg) => {
return () => {
this.context.callback(msg);
}
}
return(
<div style = { style }>
SUBSUB
<button onClick = { cb("我胡汉三又回来了!") }>点击我</button>
</div>
);
}
}
小结:注意要使用context时候,先声明自己要传的值得名称和属性,然后定义一个对象,里面有要传的内容,然后取的时候声明自己要取的值得名称和属性,然后直接this.context.属性名来用
改变context对象
想要改变context对象,只有让其和父组件的state或者props进行关联,也就是让context中的属性,与其结合,类似在context的回调函数值里面调用setState,这样state变化的时候,会更新context,然后子组件更新渲染
export default class App extends Component{
constructor(props) {
super(props);
this.state = {
color:"red"
};
}
// 父组件声明自己支持 context
static childContextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
// 父组件提供一个函数,用来返回相应的 context 对象
getChildContext(){
return{
color:this.state.color,
callback:this.callback.bind(this)
}
}
// 在此回调中修改父组件的 state,这里context对象和state绑定,所以值改变了,视图也会更新
callback(color){
this.setState({
color,
})
}
render(){
return(
<div>
<Sub></Sub>
</div>
);
}
}
// 子组件
return(
<div style = { style }>
SUBSUB
<button onClick = { cb("blue") }>点击我</button>
</div>
);
非嵌套组件通信
解决方案为:使用事件订阅 :声明一个自定义事件,然后触发第二个参数是传递的值
//首先下载events包
npm install events --save
//然后新建一个ev.js,引入包,并向外提供一个事件对象,供通信使用
import { EventEmitter } from "events";
export default new EventEmitter();
//这是主页面,Foo和Boo组件非嵌套关系
export default class App extends Component{
render(){
return(
<div>
<Foo />
<Boo />
</div>
);
}
}
//这是Foo页面
export default class Foo extends Component{
constructor(props) {
super(props);
this.state = {
msg:null,
};
}
componentDidMount(){
// 在组件装载完成以后// 声明一个自定义事件
this.eventEmitter = emitter.addListener("callMe",(msg)=>{
this.setState({
msg
})
});
}
// 组件销毁前移除事件监听
componentWillUnmount(){
emitter.removeListener(this.eventEmitter);
}
render(){
return(
<div>
{ this.state.msg }
我是非嵌套 1 号
</div>
);
}
}
//Boo页面
export default class Boo extends Component{
render(){
const cb = (msg) => {
return () => {
// 触发自定义事件
emitter.emit("callMe","Hello")
}
}
return(
<div>
我是非嵌套 2 号
<button onClick = { cb("blue") }>点击我</button>
</div>
);
}
}
小结:就是定义一个自定义事件,然后触发传参,那边用方法接受参数,并且使用
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!