欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

react组件之间传值

程序员文章站 2022-03-13 19:50:20
看过一些文章介绍react组件之间传值,无外乎以下几种情况:父子组件之间相互传值,兄弟节点之间传值。最常见的就是父子组件,做法也很简单:就是在父组件中直接通过props属性的方式将函数或者值传给子组件。父组件有变化,相应的值就会体现在子组件中;子组件有动作发生,则调用函数,函数是父组件传递过来的,父组件就能获取子组件的值。 还有一种情况,就是兄弟节点之间要传值,这个还比较复杂,因为他们之间没有直接的交集,但是他们有一个共同的父组件,可以借助父组件传递值,所以还是回到了父子组件传值上。......

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

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

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

    react组件之间传值

    代码部分:

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属性传值,直接在需要传值的组件之间来通过发布订阅即可。组件内部自己维护状态的改变,而且这种方式也是可以双向的传值。

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

    react组件之间传值

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

    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

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

 

本文地址:https://blog.csdn.net/feinifi/article/details/112565060