react组件之间传值

2023-05-16

    看过一些文章介绍react组件之间传值,无外乎以下几种情况:父子组件之间相互传值,兄弟节点之间传值。最常见的就是父子组件,做法也很简单:就是在父组件中直接通过props属性的方式将函数或者值传给子组件。父组件有变化,相应的值就会体现在子组件中;子组件有动作发生,则调用函数,函数是父组件传递过来的,父组件就能获取子组件的值。

    还有一种情况,就是兄弟节点之间要传值,这个还比较复杂,因为他们之间没有直接的交集,但是他们有一个共同的父组件,可以借助父组件传递值,所以还是回到了父子组件传值上。

    这里有个需求:有一个菜单列表,点击菜单会选择相应的选项,有一个标签页选项,点击标签可以切换选项。菜单和标签页可以产生一种联动,他们是两个兄弟节点,现在需要考虑的是选择菜单,标签页也跟着动,标签页选择的时候,菜单也跟着响应,这个示例可以很好的演示多种情况传值,效果如下所示:

    

    代码部分:

import React,{useState} from 'react'
import {Tabs,Menu,Divider} from 'antd'
import 'antd/dist/antd.css'
const {TabPane}  = Tabs

const MenuList = (props)=>{
	const {current,setCurrent} = props;
	const handleClick = e =>{
		setCurrent(e.key)
	}
	return <Menu onClick = {handleClick} selectedKeys = {current} >
				<Menu.Item key="a">aaa</Menu.Item>
				<Menu.Item key="b">bbb</Menu.Item>
				<Menu.Item key="c">ccc</Menu.Item>
			</Menu>
}

const TabComponents = (props)=>{
	const {activeKey,setActiveKey} = props;
	const changeTabHandler = (key)=>{
		setActiveKey(key)
	}
	return <Tabs activeKey={activeKey} onTabClick = {changeTabHandler}>
				<TabPane tab="aaa" key="a">this is aaa</TabPane>
				<TabPane tab="bbb" key="b">this is bbb</TabPane>
				<TabPane tab="ccc" key="c">this is ccc</TabPane>
		   </Tabs>
}
const MyTabs = ()=>{
	const [activeKey,setActiveKey] = useState('a')
	return <div>
		<MenuList setCurrent = {setActiveKey} current={activeKey}/>
		<Divider/>
		<TabComponents activeKey = {activeKey} setActiveKey = {setActiveKey}/>
	</div>
}

export default MyTabs

    这里使用了antd中的Menu和Tabs控件形成MenuList和TabComponents,他们组成一个新的组件MyTabs,在父组件中,我们通过useState函数定义了一个变量和设置变量的方法,分别对应activeKey,setActiveKey,最终将他们都传入MenuList和TabComponents中。

    这种做法,达到了联动的效果,却破坏了Tabs默认的onTabClick事件,本来Tabs的切换是根据用户点击来做切换标签页,但是现在变成了既可以手动也可以自动,手动就是,用户点击菜单选项,通过外部传入值,切换tab,这里是通过改变默认值activeKey的方式实现,如果我们不添加onTabClick函数响应,那么用户点击标签页会失效。

    ==========================================================================

    还有一种做法,可以通用,不仅可以父子之间,还可以是兄弟节点之间传值,就是发布订阅模式。这种方式,不需要父节点来维护值的状态,因此也不需要通过props属性传值,直接在需要传值的组件之间来通过发布订阅即可。组件内部自己维护状态的改变,而且这种方式也是可以双向的传值。

    先上效果图,跟上面没什么两样:

    

    代码需要增加一个简单的发布订阅实现:

    EventEmmiter.js

const EventEmmiter = {
	_events:{},
	dispatch:function(event,data){
		if(!this._events[event])
			return;
		for(var i=0;i<this._events[event].length;i++)
		{
			this._events[event][i](data);
		}
	},
	subscribe:function(event,callback){
		if(!this._events[event])
			this._events[event] = []
		this._events[event].push(callback)
	}
}
export default EventEmmiter

    PubSub.js

import React,{useState} from 'react'
import {Menu,Tabs,Divider} from 'antd'
import EventEmmiter from '../utils/EventEmmiter'
import 'antd/dist/antd.css'
const {TabPane} = Tabs
const MenuList = (props)=>{
	const [current,setCurrent] = useState('a');
	const clickHandler = (e)=>{
		EventEmmiter.dispatch('changeTab',e.key)
		setCurrent(e.key)
	}
	EventEmmiter.subscribe('changeMenu',(key)=>{
		setCurrent(key)
	})
	return <Menu onClick = {clickHandler} selectedKeys = {current}>
		<Menu.Item key="a">aaa</Menu.Item>
		<Menu.Item key="b">bbb</Menu.Item>
		<Menu.Item key="c">ccc</Menu.Item>
	</Menu>
}

const TabComponent = (props)=>{
	const [current,setCurrent] = useState('a');
	const clickHandler = (e)=>{
		EventEmmiter.dispatch('changeMenu',e)
		setCurrent(e)
	}
	EventEmmiter.subscribe('changeTab',(key)=>{
		setCurrent(key)
	})
	return <Tabs activeKey={current} onTabClick = {clickHandler}>
		<TabPane key="a" tab="xxx">xxx this is aaa.</TabPane>
		<TabPane key="b" tab="yyy">yyy this is bbb.</TabPane>
		<TabPane key="c" tab="zzz">zzz this is ccc.</TabPane>
	</Tabs>
}

const PubSub = ()=>{
	return <div>
		<MenuList/>
		<Divider/>
		<TabComponent/>
	</div>
}

export default PubSub

     这种方式比起前面,代码量虽然有增加,但是它却是一种通用的做法,不用考虑组件的关系。发布订阅是分开的,他们各自作用在不同的组件里面,是成对出现的。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

react组件之间传值 的相关文章

随机推荐

  • Nginx核心模块内置变量

    本文根据Nginx官网整理了Nginx的ngx http core module模块的内置变量 xff0c 可与Apache做对比参考 随后做了一次测试观察各变量的值 xff0c 并附上测试结果 1 变量列表 arg name 请求行中参数
  • js属性名用变量代替

    在前端中 xff0c 我们有时候需要利用变量名来设置属性名 xff0c 虽然不是很常见 xff0c 但是也是一个应用场景 这时候 xff0c 我们如果想当然的 xff0c 直接使用变量来设置 xff0c 那么可能不会达到我们想要的结果的 我
  • nodejs利用ffi库调用windows系统user32库函数获取桌面程序窗口大小

    ffi库是npm提供的操作windows系统库函数的依赖库 xff0c 安装过程会比较麻烦 xff0c 需要编译 xff0c 可能需要npm全局安装windows build tools xff0c 如何安装 xff0c 可以参照这里 这篇
  • nodejs利用ffi库调用windows系统user32函数模拟用户登录操作

    如题所示 xff0c 一般的桌面程序 xff0c 用户登录很简单 xff0c 就是找到用户名和密码输入框 xff0c 输入相应的用户名和密码 xff0c 然后点击 登录 按钮 xff0c 完成登录操作 这是人为操作的步骤 xff0c 如果这
  • 通过vue指令创建electron-vue模板项目出现一直“downloading template“问题

    今天试了一下 xff0c vue init simulatedgreg electron vue vueapp的时候 xff0c 在命令行下一直downloading template xff0c 让我很懊恼 原来vue init创建的时候
  • electron-vue与vuetify整合出现报错:If you‘re seeing “$attrs is readonly“

    如题所示 xff0c 正常情况下electron vue与vuetify的整合 xff0c 因为就是vue与vuetify的整合 xff0c 按照一般的推荐方法 xff0c 基本不会出错 xff0c 但是 xff0c 这里因为electro
  • VISA编程实例(C实现)

    今天写这个文章 xff0c 是因为自己工作中用到了ROHDE amp SCHWARZ xff08 即罗德 施瓦茨公司 xff09 的仪表设备 xff0c 需要通过编程的方式来读取仪表上功率测试结果 xff0c 本来仪表上显示了测试结果 xf
  • mac下通过gcc命令手动编译动态链接库示例

    编译动态链接库 xff0c windows linux mac平台各不相同 xff0c 从文件上来说 xff0c windows下是dll xff0c linux下是so xff0c mac下是dylib xff1b 命令上也会有区别 xf
  • c++中char[]与char*的转换以及char*与数字互转

    在c c 43 43 中 xff0c 字符串操作不可避免 xff0c 而且通常 xff0c char 或者char 就能表示字符串 xff0c 这个跟java语言有很大的差别 xff0c java中char是字符 xff0c string才
  • electron项目构建打包缺少dll文件的问题解决办法

    最近 xff0c 在做electron项目中 xff0c 使用了第三方dll xff0c 开发环境运行一切正常 xff0c 可是当我们打包 xff0c 最后生成的可执行程序再执行 xff0c 发现调用dll总是不成功 xff0c 猜测是少了
  • c/c++中的回调函数

    c c 43 43 中的回调函数是一个很奇怪的东西 xff0c 在java中 xff0c 方法调用的时候 xff0c 参数最多可以传入另一个对象实例 xff0c 然后在方法体内 xff0c 调用实例的方法 xff0c 做不到方法调用的时候
  • 在Windows下配置多个git账号

    本文记录在Windows下配置两个github账号的过程 1 生成并部署SSH key 安装好Git客户端后 xff0c 打开git bash xff0c 输入以下命令生成user1的SSH Key xff1a ssh keygen t r
  • windows命令行下通过cl命令编译动态链接库示例

    一般在windows下写一个c c 43 43 的动态链接库 xff0c 我们都是在visual studio或着visual c 43 43 这些ide里面进行编译和生成的 xff0c 今天介绍 xff0c 如何通过命令行来实现手动编译和
  • gdb命令调试c程序

    一般开发c语言程序 xff0c 都是在ide中编码 xff0c 调试也是使用集成环境 xff0c 有时候 xff0c 我们的程序是在文本编辑器中编写的 xff0c 这时候可能使用gcc编译 xff0c 然后运行可执行程序 遇到需要调试的场景
  • 选择排序算法与示例详解(c语言)

    选择排序是排序算法的一种 xff0c 思想就是 xff0c 每一轮寻找数组中最大的值或者最小的值 xff0c 放在头部或者放入一个新的数组 这样经历一轮遍历 xff0c 数组或者新数组就是排好序的 xff0c 他的目的很明确 xff0c 每
  • 2020年csdn盘点

    十年前就注册了csdn账号 xff0c 之后一直没有写过博客 xff0c 都是看别人的博客 xff0c 等到2015年左右发表了第一篇自己的博客 xff0c 直到2016年底觉着做技术的就需要记录自己的博客 xff0c 不仅是自己学习的过程
  • chrome浏览器安装react-devtools

    react devtools是react开发时的一个浏览器插件 xff0c 对于各大主流高级浏览器都有扩展程序可以安装 xff0c 官方的地址默认是https github com facebook react devtools xff0c
  • react+typescript项目构建

    react项目构建可以很简单 xff0c 但是如果是结合typescript xff0c 其实也不是很麻烦 xff0c 官网也有很明确的说明 有两种办法 xff1a 1 直接构建带有typescript的react项目 xff0c 我们需要
  • react项目启动报错:Uncaught TypeError: Cannot read property ‘forEach‘ of undefined

    如题 xff0c react项目启动报错 xff0c 具体信息 xff0c 如下所示 xff1a 这个问题是因为浏览器安装了react devtools扩展程序导致的 xff0c 很多人的解决办法就是直接禁用react devtools x
  • react组件之间传值

    看过一些文章介绍react组件之间传值 xff0c 无外乎以下几种情况 xff1a 父子组件之间相互传值 xff0c 兄弟节点之间传值 最常见的就是父子组件 xff0c 做法也很简单 xff1a 就是在父组件中直接通过props属性的方式将