目录
1、父组件向子组件传递数据(Props)
父组件:
import React, { Component } from 'react'
// 引入子组件
import Children from '../Children/Children'
export default class Parent extends Component {
render() {
let curTime = new Date().toLocaleDateString();
curTime = curTime.replaceAll('/',' - ');
return (
<div>
{/* 展示子组件,给子组件传递一个数据 */}
<Children curTime={curTime}/>
</div>
)
}
}
下载 prop-types,给 props 添加约束:
npm i prop-types
import React, { Component } from 'react'
// 引入 prop-types
import propTypes from 'prop-types'
export default class Children extends Component {
// 配置 props 约束
static propTypes = {
// 字符串类型,必须
// curTime:propTypes.string.isRequired // 这样写,即使是空字符串也满足
// 自定义校验方式,第一个参数为一整个props对象,第二个参数为当前约束属性名,第三个对象为当前组件名
curTime:(prop, propName, componentName)=>{
// 当父组件Parent传递字符串为:2023 - 4 - 26 时,输出为
// Object:{curTime:'2023 - 4 - 26'} curTime Children
console.log(prop,propName,componentName);
let temp = prop[propName].split('-');
if(temp.length !== 3){ // 简单的用拆分字符串的形式来检查一下
return new Error('格式错误'); // 校验不通过需要返回一个错误对象,会在控制台中打印
// 即使不通过,返回了一个错误对象,该不满足要求的数据仍然会展示到页面对应位置中
}
}
}
render() {
// 从父组件中接收到指定的数据
const {curTime} = this.props;
return (
<div>
<h1 style={{color:'red',fontWeight:600}}>时间:{curTime}</h1>
</div>
)
}
}
2、子组件向父组件传递数据
需要父组件提前定义一个函数,然后该函数需要的参数就是子组件向父组件传的数据,函数体的内容可以是在父组件中处理该参数(子组件传过来的数据),也可以把数据传给其他的子组件实现兄弟组件之间的通信等。
子组件 Children,用于提供用户输入环境。
import React, { Component } from 'react'
// 提供输入框让用户输入内容,并利用父组件给的函数,将数据传给父组件
export default class Children extends Component {
state = {
inpVal:''
}
collectData(e){
// 更新身上的属性
this.setState({
inpVal:e.target.value
})
// 调用父组件给的函数,将数据传递过去
this.props.sendData(e.target.value);
// this.setState 是异步方法 故不能写成以下的形式
// this.props.sendData(this.state.inpVal);
}
render() {
return (
<div style={{border:'1px solid orange',padding:'5px 10px'}}>
<input type="text" onChange={(event)=>(this.collectData(event))}/>
</div>
)
}
}
子组件 Children_a 用于实时展示用户输入的内容。
import React, { Component } from 'react'
// 实时展示用户输入的内容
export default class Children2 extends Component {
render() {
return (
<div style={{border:'1px solid green',padding:'5px 10px',minHeight:'40px'}}>
<div>{this.props.content}</div>
</div>
)
}
}
父组件 Parent。接收到 Children 组件中用户输入的数据,将该数据传给 Children_a。
import React, { Component } from 'react'
// 引入两个子组件
import Children from '../Children/Children';
import Children_a from '../Children_a/Children_a'
export default class Parent extends Component {
state = {
data:''
}
render() {
return (
<div>
{/* 该函数实时修改 state 中对应的数据,当state更新,重新调用render */}
<Children sendData={(data)=>{
this.setState({
data
})
}}/>
<Children_a content={this.state.data}/>
</div>
)
}
}
3、任意组件间通信(消息订阅与发布)
使用 PubSub-js 库。安装:
npm i pubsub-js
在项目中引入:
import PubSub from 'pubsub-js'
三个主要的函数:
1、PubSub.subscribe('订阅消息名', 处理函数); —— 订阅消息
2、PubSub.unsubscribe('取消订阅的消息名'); —— 取消订阅
3、PubSub.publish('消息名', 数据);—— 发布消息
组件 InputArea ,用于提供用户输入环境,并实时发布消息,传递用户输入的完整内容作为消息的数据。
import React, { Component } from 'react'
// 引入消息订阅与发布库
import PubSub from 'pubsub-js'
// 引入对应的Scss样式文件
import './InputArea.scss'
// 受控组件,实时监听 input 的改变,并实时发布指定的消息
export default class InputArea extends Component {
inpval = React.createRef();
inputHandler = ()=>{
// 发布 showDate 类的消息,传递此时输入框中的内容作为参数
PubSub.publish('showData',this.inpval.current.value);
}
render() {
return (
<div>
<input ref={this.inpval} type="text" className='inp'
onChange={this.inputHandler} placeholder='请输入随意内容,将展示到下方区域'/>
</div>
)
}
}
组件 CollectInput 。订阅用户输入的消息,将用户输入的数据实时更新到面板中。
import React, { Component } from 'react'
// 引入消息订阅与发布库
import PubSub from 'pubsub-js'
// 引入对应的Scss样式文件
import './CollectInput.scss'
export default class CollectInput extends Component {
state = {
receiveData:''
}
componentDidMount(){
// 当前组件定阅 showData 类的消息
PubSub.subscribe('showData',(msg,data)=>{
// 当接收到新的消息时,执行此回调函数,改变 state 中的 receiveData
this.setState({receiveData:data});
})
}
// 在组件即将要被卸载时,取消订阅所有订阅过的消息
componentWillUnmount(){
PubSub.unsubscribe('showData');
}
render() {
return (
<div className='container'>
<p className='passage'>{this.state.receiveData}</p>
</div>
)
}
}
在 App 组件中使用这两个组件:
import React from 'react';
import InputArea from './components/InputArea/InputArea'
import CollectInput from './components/CollectInput/CollectInput'
export default class App extends React.Component{
render(){
return(
<div>
<InputArea/>
<CollectInput/>
</div>
)
}
}