React-组件通讯
❤ React-组件通讯
组件通讯将教我们的内容:
- 能够使用道具接收数据
- 能够实现父子组件之间的通讯
- 能够实现兄弟组件之间的通讯
- 能够给组件添加道具校验
- 能够说出生命周期常用的钩子函数
- 能够知道高阶组件的作用
1、 组件通讯介绍
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。
在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。而在这个过程中,多个组件之间不可避免的要共享某些数据为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通讯。
换个意思说就是,大家之间总是需要沟通的呗
2、 组件的props
组件是封闭的,要接收外部数据应该通过 props 来实现props的作用:接收传递给组件的数据传递数据:给组件标签添加属性 接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据
类组件和函数式组件传递参数进行通讯如下图所示:(推荐函数式组件)
函数式组件的方式:
import React from 'react';
function Hello(props) {
// 输出接收到的 props
console.log(props);
// 返回 JSX 元素
return (
<div>接收到数据: {props.name}, 年龄: {props.age}</div>
);
}
// 使用 Hello 组件并传递 props
function App() {
return (
<Hello name="jack" age={19} />
);
}
export default App;
类组件的方式:
import React from 'react';
class Hello extends React.Component {
render() {
return (
<div>接收到的数据: {this.props.age}</div>
);
}
}
class App extends React.Component {
render() {
return (
<div>
<Hello name="jack" age={19} />
</div>
);
}
}
export default App;
函数组件props
使用案例方法
import React from 'react';
import ReactDOM from 'react-dom';
// 1. 接收数据的 Hello 组件
const Hello = (props) => {
// props 是一个对象
console.log(props);
return (
<div>
<h1>props: {props.name}</h1>
</div>
);
}
// 2. 传递数据并渲染组件
ReactDOM.render(<Hello name="jack" age={19} />, document.getElementById('root'));
类组件this.props
import React from 'react';
import ReactDOM from 'react-dom/client';
class Hello extends React.Component {
render() {
// 打印传入的 props
console.log(this.props);
return (
<div>
<h1>props: {this.props.name}</h1>
</div>
);
}
}
// 在 React 18 中使用 createRoot
const root = ReactDOM.createRoot(document.getElementById('root'));
// 渲染 Hello 组件并传递 props
root.render(<Hello name="jack" age={18} />);
组件props三个特点:
① 可以给组件传递任意类型的数据
② props是只读的对象,只能读取属性的值,无法修改对象
③ 注意:使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取props
-
可以给组件传递任意类型的数据
-
props 是只读的对象,只能读取属性的值,无法修改对象
-
注意:使用类组件时,如果写了构造函数,应该将 props 传递给 super(),否则,无法在构造函数中获取到 props !
import React from 'react';
class Hello extends React.Component {
// 构造函数接收 props,并传递给父类构造函数
constructor(props) {
super(props); // 推荐将 props 传递给父类构造函数
}
render() {
// 使用 this.props 访问传递的数据
return <div>接收到的数据: {this.props.age}</div>;
}
}
// 使用 ReactDOM 来渲染组件,假设我们有一个 ID 为 'root' 的元素
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
// 渲染 Hello 组件并传递 props
root.render(<Hello age={18} />);
3、 组件通讯的三种方式
父子、子父、兄弟组件
import React from 'react';
import ReactDOM from 'react-dom';
// 父组件
class Parent extends React.Component {
// 定义父组件的 state
state = {
lastName: '王',
};
render() {
return (
<div className="parent">
父组件:
{/* 传递 lastName 给子组件 */}
<Child name={this.state.lastName} />
</div>
);
}
}
// 子组件
const Child = (props) => {
console.log('子组件:', props); // 打印接收到的 props
return (
<div className="child">
<p>子组件,接收到父组件的数据: {props.name}</p>
</div>
);
};
// 渲染父组件
ReactDOM.render(<Parent />, document.getElementById('root'));
(1)传递方式1
-
父组件提供要传递的state数据
-
给子组件标签添加属性,值为 state 中的数据
-
子组件中通过 props 接收父组件中传递的数据
import React from 'react';
import ReactDOM from 'react-dom';
// 父组件
class Parent extends React.Component {
// 定义父组件的 state
state = {
lastName: '王', // 设置lastName的初始值
};
render() {
return (
<div>
传递数据给子组件:
{/* 传递 state 中的 lastName 给子组件 */}
<Child name={this.state.lastName} />
</div>
);
}
}
// 子组件
function Child(props) {
return <div>子组件接收到数据: {props.name}</div>;
}
// 渲染父组件到页面
ReactDOM.render(<Parent />, document.getElementById('root'));
(2)传递方式2
子组件传递数据给父组件
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数
- 父组件提供一个回调函数(用于接收数据)
- 将该函数作为属性的值,传递给子组件
import React from 'react';
import ReactDOM from 'react-dom';
// 父组件
class Parent extends React.Component {
// 父组件方法,接收子组件数据
getChildMsg = (msg) => {
console.log('接收到子组件数据', msg);
};
render() {
return (
<div>
子组件:
{/* 将父组件的方法传递给子组件 */}
<Child getMsg={this.getChildMsg} />
</div>
);
}
}
// 子组件
function Child(props) {
// 模拟子组件发送消息
const sendMessage = () => {
props.getMsg('来自子组件的消息');
};
return (
<div>
<button onClick={sendMessage}>点击发送消息给父组件</button>
</div>
);
}
// 渲染父组件到页面
ReactDOM.render(<Parent />, document.getElementById('root'));
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数。
3.子组件通过 props 调用回调函数
import React from 'react';
import ReactDOM from 'react-dom';
// 子组件
class Child extends React.Component {
// 定义子组件的 state
state = {
childMsg: 'React',
};
// 处理点击事件,向父组件传递数据
handleClick = () => {
this.props.getMsg(this.state.childMsg); // 调用父组件传递的 getMsg 方法
};
render() {
return (
<div>
<button onClick={this.handleClick}>点我,给父组件传递数据</button>
</div>
);
}
}
// 父组件
class Parent extends React.Component {
// 父组件接收子组件的数据
getChildMsg = (msg) => {
console.log('接收到子组件的数据:', msg);
};
render() {
return (
<div>
<h1>父组件</h1>
{/* 将父组件的方法传递给子组件 */}
<Child getMsg={this.getChildMsg} />
</div>
);
}
}
// 渲染父组件到页面
ReactDOM.render(<Parent />, document.getElementById('root'));
案例
import React from 'react';
import ReactDOM from 'react-dom/client'; //React 18
import './index.css'
class Parent extends React.Component{
state={
lastName:'父亲',
}
getChildMsg=(msg)=>{
console.log('接收到子组件数据',msg);
this.setState({
lastName:msg
})
}
render(){
return (
<div className='parent'>
父组件:
{this.state.lastName}
<Child getMsg={this.getChildMsg}></Child>
</div>)
}
}
class Child extends React.Component{
state={
msg:'行为'
}
handleClick=()=>{
this.props.getMsg(this.state.msg);
}
render(){
return (
<div className='child'>
子组件:<button onClick={this.handleClick}> 传递数据给付组件</button>
</div>)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Parent name='jack' age={18} colors={['red','green','blue']}
fn={()=>{console.log('这是一个组件传递函数')}} tag={<p>设置一个p标签</p>}/>);
(3)兄弟组件通讯
(4)context
使用步骤:
1.调用 React. createContext() 创建 Provider(提供数据)和 Consumer(消费数据)两个组件。
const { Provider, Consumer }= React.createContext()
2.使用 Provider 组件作为父节点。
<Provider>
<div className="App">
<Child1 />
</div>
</Provider>
3.设置 value 属性,表示要传递的数据。
<Provider value="pink">
<div className="App">
<Child1 />
</div>
</Provider>
4.在子组件中通过 Consumer 组件接收数据。
<Consumer>
{data => <span>data参数表示接收到的数据--{data}</span>}
</Consumer>
过程:
- 如果两个组件是远方亲戚(比如,嵌套多层)可以使用Context实现组件通讯
- Context提供了两个组件:Provider和 Consumer
- Provider组件:用来提供数据
- Consumer组件:用来消费数据
案例:
import React from 'react';
import ReactDOM from 'react-dom';
// 创建 Context
const { Provider, Consumer } = React.createContext();
// 子组件
class Node extends React.Component {
render() {
return (
<Consumer>
{(value) => <div style={{ color: value }}>这是 Node 组件</div>}
</Consumer>
);
}
}
// 父组件
class App extends React.Component {
render() {
return (
<Provider value="pink">
<div className="app">
<Node />
</div>
</Provider>
);
}
}
// 渲染父组件到页面
ReactDOM.render(<App />, document.getElementById('root'));
const child = props;
return (
<div>
<span>child > 3SSNaI6</span>
<span>是子节点 -- {data}</span>
</div>
);
- 点赞
- 收藏
- 关注作者
评论(0)