React组件通信
父子组件通信
原理: 数据 —> 父组件 —> 通过props —> 子组件
数据在父组件中,通过在调用的子组件上绑定数据,子组件的props中就会传入该数据,并提供this.props.xxx使用数据
方式一:直接绑定单个数据
// 父组件
<childre 数据名={this.state.数据名} />
// 子组件
const {数据名}=this.props
方式二:绑定整个父组件的state状态(使用展开运算符)
// 父组件
<childre {...this.state} />
// 子组件
const {数据名}=this.props
方式三:绑定整个父组件的state和props数据(整个this)
// 父组件
<childre {...this} />
// 子组件
//
const {props:{数据名},state:{数据名,数据名}}=this.props
完整示例
// 父组件
import React, { Component } from "react";
import Hello from './Hello';
interface Props{}
interface State{money:number}
export default class App extends Component<Props,State>{
state={money:10000}
render(){
const {money}=this.state
return(
<div>
<Hello money={money}/>
</div>
)
}
}
// 子组件
import React, { Component } from "react";
interface Props{money:number};
interface State{};
export default class Hello extends Component<Props,State> {
render(){
const {money}=this.props
return (
<div>
这个月发了{money}块工资
</div>
)
}
}
子父组件通信
原理: 父组件给子组件方法,子组件调用方法传值,父组件方法接收参数,并保存参数
1. state ----> 子组件
2. fn ----> 父组件
3. fn 给了 子组件
4. 子组件调用fn,并且可以传参
5. state — 父组件 —保存参数
完成案例: 子组件给父组件红包
// 父组件
import React, { Component } from "react";
import Hello from './Hello';
interface Props{}
interface State{sFq:number}
export default class App extends Component<Props,State>{
state={sFq:500}
get = (n:number)=>{
//1.接收子组件调用时传入的参数
this.setState({
//2.通过setState将传入的参数保存
sFq:this.state.sFq+n
})
}
render(){
const {sFq}=this.state
return(
<div>
<Hello get={this.get}/>
<p>{ sFq }</p>
</div>
)
}
}
// 子组件
import React, { Component } from "react";
// 给传入的方法定义类型
interface Props{get:(n:number)=>void;}
interface State{hongbao:number}
export default class Hello extends Component<Props,State> {
state={hongbao:888}
render(){
const {get}=this.props
const {hongbao}=this.state
return (
// 注意事件调用方法传值的时,需要嵌套一层箭头函数,因为直接调用得到是返回值
<div>
<button onClick={()=>{get(hongbao)}}>父亲节红包</button>
</div>
)
}
}
非父子组件通信
原理:共同父组件中定义数据或函数,进行父子通信和子父通信来实现数据的通信
方式一:原生通信
案例:姐姐打弟弟( 组件:App Sister Borther )
// App组件
import React, { Component } from 'react'
import Borther from './borther'
import Sister from './sister'
interface Props {}
interface State {flag:boolean;}
export default class App extends Component<Props, State> {
// 数据定义在这
state = {flag:false}
// 操作数据的方法
setFlag=()=>{
this.setState({
flag:!this.state.flag
})
}
render() {
return (
// 将数据修改的方法传递给sister进行子父通信
// 将数据传递给borther
<div>
<Sister setFlag={ this.setFlag }/>
<Borther {...this.state}/>
</div>
)
}
}
// Borther组件
import React, { Component } from 'react'
interface Props {flag:boolean;}
interface State {}
export default class Borther extends Component<Props, State> {
render() {
const { flag } = this.props
return (
<div>
{
flag && (
<img src="https://bpic.588ku.com/element_origin_min_pic/19/07/16/b136e2bd89c49841cace281f462418d3.jpg"/>
)
}
</div>
)
}
}
// sister 组件
import React, { Component } from 'react'
interface Props {setFlag:()=>void}
interface State {}
export default class Sister extends Component<Props, State> {
render(){
const { setFlag } = this.props
return (
<div>
<button onClick={setFlag}>打弟弟</button>
</div>
)
}
}
方式一:ref属性
区别之上是在于,共同的父级组件,可以通过ref绑定拿到子组件的方法或数据
<borther ref={(el)=>{this.borther=el}}>
跨级组件通信
-
创建上下文对象
const ctx = React.createContext(0)
-
在App组件中传值
<ctx.Provider value={ this.state.money }></ctx.Provider>
- 在Son组件中接收值
static contextType = ctx;
- 使用context
{ this.context }