React 精要面试题讲解(二) 组件间通信详解
单向数据流与组件间通信
上文我们已经讲述过,react 单向数据流的原理和简单模拟实现。结合上文中的代码,我们来进行这节面试题的讲解: react中的组件间通信。
那么,首先我们把看上文中的原生js代码:
function child(props){
this.props = props;
}
function parent(props){
this.props = props
this.state = '这是父函数的一个状态'
this.childNodes = new child(this.state);
}
console.log(new parent('这是一个属性'));
ok,经过运行,我们发现打印结果的结构 和 react父子组件的关系结构是极为类似的,子函数通过props形参接受到父函数的state。
这个好理解吧?那么在说react组件通信之前,我们基于原生继续模拟父子组件间的通信。
如上文代码所示,我们已经实现了父函数通过props这个形参向子函数传递数据——是的,相对而言,在react中,父组件通过props(规定了只能通过props传递及获取)向子组件进行数据传递。换句话讲,props这个实例属性,表面唯一的作用就是参数传值…
那么,我们接来下要思考一个问题,如何在上述代码中实现 子函数向父函数传递数据?
如果我们把函数玩的够熟练,那么很容易会思考到以下实现方式:
function child(props){
this.data = '我是子函数中的data'
props.getChildData(this.data);
this.props = props;
}
function parent(props){
this.props = props;
this.dataFromChild = null;
this.getChildData = (data)=>{
console.log('这个函数被运行了,我们拿到了传过来的参数:'+data);
this.dataFromChild = data;
}
this.childNodes = new child({
getChildData:this.getChildData
});
}
console.log(new parent('这是一个属性'));
(别偷懒!f12,复制上述代码到控制台运行!)
好的,简单说下上述代码做出的更改:
1 父函数中定义了一个函数,通过参数对象(实则就是props啊)传递给了子函数;
2 这个函数一旦被执行,会把参数data赋值给父函数中的实例属性data;
3 子函数通过props接收到了这个函数,运行了它,并且把自己的data作为参数传递了进去;
ok,那么我们经过运行,发现控制台打印的内容:

哦!!!于是我们明白了,我们写原生js的时候,就是通过:
在父函数中定义方法,通过参数传递给子函数,子函数调用这个方法并且把自己数据作为参数,那么父函数就可以通过形参拿到了~
什么?有点绕?那么说的再简单点:
父函数的方法传递给子函数,被子函数传参调用。
那么赶紧用内存不足的大脑思考思考react中是不是也可以啊?
class Child extends React.Component{
data = '我是子组件中的data'
render(){
this.props.getChildData(this.data);
return <div>我是Child组件</div>
}
}
class Parent extends React.Component{
childData=null
getChildData = (data)=>{
this.childData = data;
console.log(data);
}
render(){
return <Child getChildData = { this.getChildData } />
}
}
console.log(<Parent />)
上面的代码够简练了吧(比中指)!
那么我们运行上述代码发现——乖乖,真的拿到了~~这不还是一样吗?我们玩的不是react吗?怎么成原生js 了啊?啥啊谁啊我在哪啊??

实则所有单向数据流的js框架都可以通过上述的方式进行子组件向父组件的通信。
非常好,现在我们来整理一下react的父子组件间通信规则:
*父传子: 父组件通过props传参呗……*
*子传父 : 父组件通过props传参呗……*
啥? 我写重了?
(哼哼一声我露出了鄙视的微笑,并在下面多写了一行)
***子传父完整版: 父组件中定义函数,通过props传递给子组件,子组件调用这个函数并传参。***
嗯…经过思考,我们得出了这样一个结论: 子传父这样的逆向通信,实际也是符合单向数据流的概念。无非就是把函数当做参数传递下去而已啊!!!(重点是这句啊~~~react中的逆向通信的方式和单向数据流完全不冲突啊~)
子传父(逆向通信)的其他方式
除开上面讲过的 父组件中定义函数传递给子组件并被其调用 这种js通用方式,在react中我们还可以怎样玩?
在Vue,React中都有ref 这样一个特殊的实例属性。
react中 ref 具备两种作用:
1 标记dom的话,能获取dom实例;
2 标记子组件的话,能获取子组件实例的所有数据(包括子组件的props,state,定义的方法,实例…)。
那么也就是说,父组件通过this.ref就拿到子组件的任何数据了…就这么简单啊。
当然,依照react的尿性,文档中特意提到了一点:不要轻易用这玩意啊,危险啊,别冲动啊小伙子们~
事实上,经过react的版本变化,ref赋值目前有三种方式 : 字符串、回调、 CreateRef() //这个是16.3后的新增api
迭代维护做的都很到位啊~ 凭啥只用在表单控件里啊~
当然,关于ref的花式玩法我们会在本系列后面内容讲到。
远亲组件的通信
其实无论做react还是vue或者其他项目,我们必须要明确,写的还是js。(这也是为什么我一直把原生和react放在一起讲)
那么远亲组件的通信,我们即时对react毫无了解,也能至少说出一万种方式…
例如:
1 通过缓存 : 组件A把数据存到缓存中,组件B就可以从中取出;
2 通过url : 通过location对象拿到…;
3 通过与后端配合: 组件A把数据扔到接口里去,组件B可以从中拿到…;
以上方式,我称之为通过第三方媒介的形式。
(插一句: 有木有觉得redux中store共享跟session级别缓存很类似?)
也就是说,远亲组件的通信,我们抛开react去思考得出一个结论:
——通过第三方媒介作为一个存储地点,实现数据共享。
ok我们把话题转回来。react中,同系远亲的话(太太爷爷到重重孙子),完全可以通过context嘛(上一篇有讲,后面也会出context的专章)…
至于不是很远的关系, 利用props一层一层往内传啊。 (例如爷爷传到孙子)
逆向: 子调用爷爷的函数并传参就实现了子传爷爷;
同级 : 子1传父,父传子2 ;
很远关系: 1 context(自己实现试试啊~) 2 通过第三方媒介共享( 缓存,url,服务端,以及后面我们会讲到的redux,react-redux,dva等全局状态存储管理插件);
我们发现,就单单react的话,传来传去还是 父传子 子传父啊……最多特殊情况用到context(无论多远的关系,最终肯定有个统一的祖宗啊<App ==!/>)而已啊~
总结
这章讲述了react的基础必面的面试题:
如何在react项目中实现组件间的通信。
也可能会引发一些react与项目与原生的思考(这是我想要的)。
如果本章内容对您有帮助,请点个推荐哦~
React 精要面试题讲解(二) 组件间通信详解的更多相关文章
- React 精要面试题讲解(五) 高阶组件真解
说明与目录 在学习本章内容之前,最好是具备react中'插槽(children)'及'组合与继承' 这两点的知识积累. 详情请参照React 精要面试题讲解(四) 组合与继承不得不说的秘密. 哦不好意 ...
- React 精要面试题讲解(一) 单向数据流
react 单向数据流概念 'react框架是怎样的数据流向?'||'react单向数据流是怎样的概念 ?' 解答这个问题之前,我们首先得知道,js框架是个怎样的概念. 框架:具备一定**编程思想** ...
- react组件间传值详解
一.父子组件间传值 <1>父传子 父组件:
- vue组件间传值详解
1.父传子----传值要点: <1> 在组件注册的时候必须要使用 return 去返回 data对象;
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...
- Vue 根组件,局部,全局组件 | 组件间通信,案例组件化
一 组件 <div id="app"> <h1>{{ msg }}</h1> </div> <script src=" ...
- react系列(三)组件间通信
组件间通信 React的基本组件元素是一个个组件,组件之间可能存在关联.组合等关系.不同的组件之间,经常会发生数据传递或者交换,我们称之为组件间通信. 根据传递的复杂程度,可以分为三种情况: 父子间通 ...
- React 组件间通信介绍
React 组件间通信方式简介 React 组件间通信主要分为以下四种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件之间通信 非嵌套组件间通信 下面对这四种情况分别进行介绍: 父组件向子 ...
- React的组件间通信
一.React的单向数据流 React是单向数据流,数据主要从父节点传递到子节点(通过props).如果顶层(父级)的某个props改变了,React会重渲染所有的子节点.这通常被称为“自顶向下”或“ ...
随机推荐
- BASE64编码原理分析脚本实现及逆向案例
在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理你又了解多少?今天小编带大家了解一下Base64编码原理分析脚本实现及逆向案例的相关内容. 01编码由来 数 ...
- 入门PHP你需要了解些什么?
1.[PHP]PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛 ...
- PHP内核之旅-6.垃圾回收机制
回收PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6 ...
- 三种方式实现观察者模式 及 Spring中的事件编程模型
观察者模式可以说是众多设计模式中,最容易理解的设计模式之一了,观察者模式在Spring中也随处可见,面试的时候,面试官可能会问,嘿,你既然读过Spring源码,那你说说Spring中运用的设计模式吧, ...
- 【自然语言处理篇】--以NLTK为基础讲解自然语⾔处理的原理和基础知识
一.前述 Python上著名的⾃然语⾔处理库⾃带语料库,词性分类库⾃带分类,分词,等等功能强⼤的社区⽀持,还有N多的简单版wrapper. 二.文本预处理 1.安装nltk pip install - ...
- Golang 入门 : 映射(map)
映射是一种数据结构,用于存储一系列无序的键值对,它基于键来存储值.映射的特点是能够基于键快速检索数据.键就像是数组的索引一样,指向与键关联的值.与 C++.Java 等编程语言不同,在 Golang ...
- myeclipse配置tomcat服务器
在进行j2EE开发时,需要进行服务器配置, 这里因为要进行servlet开发,也要配置服务器.这里以在myeclipse上配置tomcat服务器为例 这里只是做下记录,方便自己以后查看 1.打开mye ...
- 程序猿想聊天 - 創問 4C 團隊教練心得(二)
在第二天裡,主要談的是關於 Courage (勇氣) . Co-Create (共創) 的部分因為我們不是真實的團隊,就沒有繼續下去了 一早開始先回顧了一下前一天的內容,接下來我們就開始玩小遊戲 這個 ...
- 04 入门 - ASP.NET MVC应用程序的结构
目录索引:<ASP.NET MVC 5 高级编程>学习笔记 用Visual Studio创建了一个新的ASP.NET MVC应用程序后,将自动向这个项目中添加一些文件和目录. 如图所示: ...
- 看完我身边前卫时尚女孩的手机 这几款APP强烈推荐
爱美之心,人皆有之,爱美是所有人生追求里最有价值的生活状态,美是一种能力,更是一种修养,懂得打扮自己的女人更受欢迎 因为她们懂得什么是美.想要变美的女孩们不要着急,下面几款爱美工具定会让你一见钟情. ...