1. 前言
- 组件通信 不管在哪个框架里面 基本都属于最基本,最常用的了,那就唠唠吧
2. 是什么 what
- 组件通信 那就是组件之间进行通信嘛
- 组件之间有各种关系 父子 兄弟 跨级等
- 通信就是 互相聊天 有来有往
3. 场景总结
- 不总结场景回答的就太木有逻辑性了
- 父组件向子组件传递
- 子组件向父组件传递
- 兄弟组件之间的通信
- 父组件向后代组件传递
- 非关系组件传递
4. 父组件向子组件传递
1.React的数据流动为单向的,父组件向子组件传递是最常见的方式
- 父组件在调用子组件的时候,只需要在子组件标签内传递参数,子组件通过props属性就能接收父组件传递过来的参数
// ParentComponent.jsx import React from 'react'; import ChildComponent from './ChildComponent'; const ParentComponent = () => { const data = 'Hello, Child!'; return ( <div> <ChildComponent data={data} /> </div> ); }; // ChildComponent.jsx import React from 'react'; const ChildComponent = (props) => { return <div>{props.data}</div>; }; export default ChildComponent;
- 父组件向子组件传递 就是 通过 props
5. 子组件向父组件传递
1.父组件
import React, { useState } from 'react'; import ChildComponent from './ChildComponent'; const ParentComponent = () => { const [message, setMessage] = useState(''); const handleMessage = (msg) => { setMessage(msg); }; return ( <div> <h1>Parent Component</h1> <p>Message from child: {message}</p> <ChildComponent onMessage={handleMessage} /> </div> ); }; export default ParentComponent;
子组件
import React from 'react'; const ChildComponent = ({ onMessage }) => { const handleClick = () => { onMessage('Hello from child!'); }; return ( <div> <h2>Child Component</h2> <button onClick={handleClick}>Send Message to Parent</button> </div> ); }; export default ChildComponent;
- 组件
ParentComponent
通过将一个回调函数 handleMessage 作为 onMessage 属性传递给子组件ChildComponent
,子组件
内部的按钮点击事件会触发handleClick
函数,- 然后调用父组件传递的回调函数
onMessage
,将消息作为参数传递给父组件。- 父组件接收到消息后,更新状态并在页面上显示
6. 兄弟组件之间通信-Context
- 通过创建上下文提供者和使用上下文消费者实现跨组件层级的数据传递
- 代码
// DataContext.js import React from 'react'; const DataContext = React.createContext(); export default DataContext; // ParentComponent.jsx import React from 'react'; import ChildComponent from './ChildComponent'; import DataContext from './DataContext'; const ParentComponent = () => { const data = 'Hello, Child!'; return ( <DataContext.Provider value={data}> <ChildComponent /> </DataContext.Provider> ); }; // ChildComponent.jsx import React, { useContext } from 'react'; import DataContext from './DataContext'; const ChildComponent = () => { const data = useContext(DataContext); return <div>{data}</div>; }; export default ChildComponent;
7. 非关系组件传递 -redux
- 代码
// actions.js export const setData = (data) => ({ type: 'SET_DATA', payload: data, }); // reducers.js const initialState = { data: '', }; export const dataReducer = (state = initialState, action) => { switch (action.type) { case 'SET_DATA': return { ...state, data: action.payload, }; default: return state; } }; // ParentComponent.jsx import React from 'react'; import { connect } from 'react-redux'; import { setData } from './actions'; const ParentComponent = (props) => { const handleClick = () => { props.setData('Hello, Child!'); }; return ( <div> <button onClick={handleClick}>Set Data</button> </div> ); }; const mapDispatchToProps = { setData }; export default connect(null, mapDispatchToProps)(ParentComponent); // ChildComponent.jsx import React from 'react'; import { connect } from 'react-redux'; const ChildComponent = (props) => { return <div>{props.data}</div>; }; const mapStateToProps = (state) => ({ data: state.data, }); export default connect(mapStateToProps)(ChildComponent);
8. 通信方式表格对比
方式 | 描述 | 使用场景 | 优点 | 缺点 |
Props | 通过父组件向子组件传递数据 | 单向数据流、父子组件之间的简单通信 | 简单易用,适用于简单组件间的通信 | 只适用于父子组件之间的通信,组件层级较深时传递麻烦 |
Context | 创建上下文提供者和使用上下文消费者实现跨组件层级的数据传递 | 跨组件层级的数据共享,避免逐层传递数据 | 可以避免 Props 层层传递的麻烦 | 上下文的更新会引发整个消费者子树的重新渲染,性能开销较大 |
Redux | 使用状态管理库Redux进行全局状态管理,实现组件之间的通信 | 多个组件共享状态、组件之间的复杂通信 | 全局状态管理,方便组件之间的通信和状态共享 | 代码复杂,需要引入额外的依赖和配置,对于简单场景会增加开发成本 |
EventEmitter | 使用事件订阅-发布模式,通过事件触发和监听实现组件之间的通信 | 非父子组件之间的通信、跨组件层级的通信 | 灵活、适用于非父子组件之间的通信 | 事件订阅和发布的管理可能较为复杂,不易维护 |
Callback | 通过回调函数将数据传递给父组件或其他组件 | 子组件向父组件传递数据或组件之间的双向通信 | 简单明了,适用于父子组件之间的通信或组件之间的双向通信 | 如果层级较深,需要逐层传递回调函数,可能导致代码冗余和维护困难 |
Refs | 通过引用ref来直接访问子组件的实例或DOM元素,实现父组件对子组件的操作或访问 | 访问子组件的实例或DOM元素、触发子组件的方法 | 可以直接访问子组件的实例或DOM元素,灵活性高 | 破坏了React的数据流一致性,不推荐过度使用 |