React组件的通信
- 父子组件通信
- 子父组件通信
- 非父子组件通信
- 跨组件通信
1. 父子组件通信
- 无论传递props(属性)还是state(状态),子组都通过props来接收
- props获取的两种方法
- 定义在标签属性中通过
this.props.name
- 定义
<Son name="子组件通过this.props.name调用"></Son>
- 定义
- 定义在组件内容中通过
this.props.children
调用- 定义
<Son>{this.state}</Son>
- 定义
- 定义在标签属性中通过
- 代码:
Father组件- - - -> Father.jsx
Son组件- - - ->Son.jsximport React, {Component,Fragment} from "react" import Son from "./son"//引入子组件 class Father extends Component{ constructor(){ super() this.state = { id:1, userName:'Father' name:'Father组件的state' } render(){ return( <Fragment> <h3>Father组件</h3> <p>Father组件的state:{this.state.userName}</p> {/*父子之间的传值*/} <Son name="Son->props">{this.state}</Son> </Fragment> ) } } export default Father
import React,{Component,Fragment} from "react" export default class Son extends Component{ render(){ return( <Fragment> <h3>Son组件</h3> <p>获取定义在父组件的props(属性):this.props.name</p> <p>获取Father组件的state(状态):this.props.children.userName</p> </Fragment> ) } }
- props获取的两种方法
2. 子父通信
-
父组件传递方法给子组件,子组件调用父组件的方法
-
子组件也是通过props来接受父组件的方法,并调用
注意:自己的状态自己更改
-
代码
Father.jsimport React, {Component,Fragment} from "react" import Son from "./Son.jsx" class Father extends Component{ constructor(){ super() this.state = { count:0 } } fatherCountAdd = ()=>{ this.setState( { count:this.state+1 } ) } render(){ return( <Fragment> <h3>Father组件</h3> <p>count:{this.state}</p> <Son callback={this.fatherCountAdd}></Son> </Fragment> ) } } export default Father
Son.js
import React,{Component,Fragment} from "react" class Son extends Component{ sonCountAdd = () => { this.props.callback()//调用父组件的方法 } render(){ return( <Fragment> <h3>Son组件</h3> <button onclick={this.sonCountAdd}>+</button> </Fragment> ) } } export default Son
3. 非父子通信
- ref链
ref = "xxx"
----->this.refs.xxx
【废弃】ref={ el=>this.xxx = el }
------>this.xxx
【推荐】React.createRef()
(React16.3提供)
4. 跨组件通信
- 使用context
- 定义玩context后
- 组件使用context中的数据必须定义一个静态属性
static contextType = ThemesContext
- 然后直接可以通过
this.context
来使用
- 然后直接可以通过
- 代码
建一个存放初始数据的文件 context.js
context.js
第一种import React from "react" export const themes = { light:{ name:ZhangSan; age:10 }, dark:{ userName:LiSi age:20 } } export const ThemesContext = React.Context( themes.dark //Context默认值 )
使用(子组件、非父子组件(孙子组件),跨组件使用) 任意组件下使用index.jsimport React,{Component,Fragment} import {ThemesContext} from "./context.js"//引入上面context.js文件 class ContextInitial extends Component{ static contextType = ThemesContext //组件要使用必须定义这个静态属性 render(){ return( <Fragment> <p>取得context的默认数据{this.context.userName}</p> </Fragment> ) } }
第二种
- 通过
ThemeContext.Provider
去覆盖context 的默认值 - 主要用于非父子之间的传值(孙子组件)
- 孙子组件想获取到父组件的state或props
- 方法
<ThemesContext.Provider value={this.state}></ThemesContext.Provider>
value中的值会替代默认值
- 代码
父组件 Father.js
孙子组件的获取 SonSon.jsimport React,{Component,Fragment} from "react" import Son from "./Son.js" import {ThemesContext} from "./context.js"//引入上面context.js文件 class Father extends Component{ constructor(){ super() this.state = { fatherName:Father组件的状态(state), age:25 } } render(){ return( <Frament> <ThemesContext.Procider value={this.state}> {/*这里会将父组件的state传递到子组件,以及子组件下的子组件(孙子组件)*/} <Son></Son> </ThemeContext.Provider> </Frament> ) } }
注意:这里子组件不需要使用context 就不用操作子组件
import React,{Component,Fragment} from "react" import {ThemesContext} from "./context.js"//引入上面context.js文件 class SonSon extends Component{ render(){ return( <Fragment> <p>获Father组件的state:{this.context.fatherName}</p> </Fragment> ) } }