React 组件间通信常用的大概有这么几种方式:
首先准备三个组件,他们之间的关系是:根组件 》 父组件 》 子组件
如下目录结构:
创建三个组件文件,并展示最终效果图:
父组件向子组件通信(props ):
创建父组件
import React, { useState, createContext } from 'react';
import './App.css';
import Parent from './page/parent'
const App = () => {
const msg = '1111'
const [propsMsg, setPropsMsg] = useState('这是我要传递的参数');
return (
<div className="App">
<div className='gen'>
<h1>根组件</h1>
<p>参数:{propsMsg}</p>
<Parent msg={propsMsg} />
</div>
</div>
);
}
export default App;
创建子组件
import React, {useState, useEffect} from 'react';
const Parent = (props) => {
const { msg } = props;
return (
<div className="parent">
<h2>这是父组件</h2>
<p>父组件接收根组件通过Props传递的参数:
<span style={{color: '#fff'}}>{msg}</span>
</p>
</div>
)
}
export default Parent;
子组件向父组件通信 函数回调 (注意:父子关系是相对参照物,没有绝对一说)
创建父组件
import React, { useState, createContext } from 'react';
import './App.css';
import Parent from './page/child'
const App = () => {
const [childMsg, setChildMsg] = useState('');
const getChildMsgFn = (childQueryMsg) => setChildMsg(childQueryMsg)
return (
<div className="App">
<div className='gen'>
<h1>根组件</h1>
<p>接收从子组件传递过来的数据:<span className='setChildMsgStyle'>{childMsg}</span></p>
<Parent postMsgToParentFn={getChildMsgFn} />
</div>
</div>
);
}
export default App;
创建子组件
import React, {useState, useEffect} from 'react';
const Parent = (props) => {
const { postMsgToParentFn} = props;
return (
<div className="parent">
<h2>这是父组件</h2>
<div className='setBtnStyle' onClick={() => postMsgToParentFn('这是子组件传递给父组件的数据!')}>我要向根组件传递一些数据</div>
</div>
)
}
export default Parent;
注意:红框出是子组件传递上来的将要展示的数据,箭头标注的地方表示 子组件触发事件
祖孙(后代)组件间通信,可以使用 createContext, useContext
创建根组件
import React, { useState, createContext } from 'react';
import './App.css';
import Parent from './page/parent'
const C = createContext(11111);
const App = () => {
const msg = '1111'
const [propsMsg, setPropsMsg] = useState('这是我要传递的参数');
const [childMsg, setChildMsg] = useState('');
const getChildMsgFn = (childQueryMsg) => setChildMsg(childQueryMsg)
return (
<div className="App">
<div className='gen'>
<h1>根组件</h1>
<p>参数:{msg}</p>
<p>参数:{propsMsg}</p>
<p>接收从子组件传递过来的数据:<span className='setChildMsgStyle'>{childMsg}</span></p>
<C.Provider value={{ msg, msg1: propsMsg }}>
<Parent msg={propsMsg} postMsgToParentFn={getChildMsgFn} />
</C.Provider>
</div>
</div>
);
}
export default App;
export {
C
}
创建父组件
import React, {useState, useEffect} from 'react';
import Child from './child'
const Parent = (props) => {
const { msg, postMsgToParentFn} = props;
const msgToParent = '这是子组件传递给父组件的数据!'
return (
<div className="parent">
<h2>这是父组件</h2>
<p>父组件接收根组件通过Props传递的参数:
<span style={{color: '#fff'}}>{msg}</span>
</p>
<div className='setBtnStyle' onClick={() => postMsgToParentFn(msgToParent)}>我要向根组件传递一些数据</div>
<Child/>
</div>
)
}
export default Parent;
创建子组件
import React,{useContext} from "react";
import {C} from '../App'
const Child = () => {
const {msg,msg1} = useContext(C);
return (
<div className="child">
<h3>这是子组件</h3>
<p>接收从根组件通过Context 上下文 传递过来的数据:{msg} --- {msg1}</p>
</div>
)
}
export default Child;
不相干组件间通信(不仅限于兄弟组件之间的通信) ,可以利用 node 的 api events
创建 utils.js 作为事件总线 EventBus相当于一个全局的仓库,任何组件都可以去这个仓库里获取事件 它的工作原理是发布/订阅方法,通常称为 Pub/Sub 。
import { EventEmitter } from 'events';
const eventBus = new EventEmitter();
export default eventBus;
兄弟组件1
import React,{useContext, useEffect, useState} from "react";
import eventBus from '../utils'
const Child = () => {
const [myParams, setMyParams] = useState(null);
useEffect(() => {
eventBus.on('myParams', (value) => setMyParams(value));
return () => {
eventBus.off('myParams')
}
}, [])
return (
<div className="child">
<h3>这是兄弟1组件</h3>
<p>这是我兄弟给我的数据:{myParams}</p>
</div>
)
}
export default Child;
兄弟组件2
import React,{useContext} from "react";
import eventBus from '../utils'
const Child1 = () => {
const toSubChildDataFn = () => {
eventBus.emit('myParams', '这是要给兄弟的数据!')
};
return (
<div className="child" style={{backgroundColor: 'blue'}}>
<h3>这是兄弟2组件</h3>
<div className="setBtnStyle" onClick={() => toSubChildDataFn()}>给兄弟组件传递数据</div>
</div>
)
}
export default Child1;
以上就是关于React 常用的几种数据通信方式,如果更好的方式请留言,让作者也学习一下,如果有错误,欢迎指正,谢谢。
如果本篇文章对你有帮助,麻烦请点个赞,谢谢。
最后感谢广大读者朋友的耐心阅读与包容,祝愿大家心想事成,一切随心随性。
|