主要有以下几种情况需要考虑:
- 父子
- 子父
- 兄弟
- 爷孙
1. 父子通信
- 传参:props
//父组件
import React from 'react';
import { withRouter } from 'react-router-dom';
import Child from './Child';
class Parent extends React.Component{
constructor(props){
super(props);
this.state={
name: '父组件'
}
}
render() {
return <div className=''>
<Child name={this.state.name}></Child>
</div>
}
}
export default withRouter(Parent);
----------------------------------------------------
//子组件
import React from 'react';
export default class Child extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
console.log('父组件传递的值是:', this.props.name)
}
render() {
return <div className=''>
<div>子组件content</div>
</div>
}
}
- 调用方法:refs
// 父组件
import React from 'react';
import { withRouter } from 'react-router-dom';
import Child from './Child';
class Parent extends React.Component{
constructor(props){
super(props);
this.state={
name: '父组件'
}
// 1. 创建Refs
this.myRef = React.createRef();
}
componentDidMount() {
// 2. 访问 Refs
this.myRef.current.childMethod();
}
render() {
return <div className=''>
{/*1. 创建Refs*/}
<Child name={this.state.name} ref={this.myRef}></Child>
</div>
}
}
export default withRouter(Parent);
分为两个步骤:
- 创建Refs: 通过React.createRef()创建refs,并通过 ref 属性附加到 React 元素。
this.myRef = React.createRef();
<Child name={this.state.name} ref={this.myRef}></Child>
- 访问 Refs:当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中被访问。
this.myRef.current.childMethod();
其中,ref 的值根据节点的类型而有所不同:(来自官网)
- 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
- 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
- 不能在函数组件上使用 ref 属性,因为他们没有实例。
2. 子父通信
- 传参&&调用方法:props的回调
//父组件
import React from 'react';
import { withRouter } from 'react-router-dom';
import Child from './Child';
class Parent extends React.Component{
constructor(props){
super(props);
this.state={
}
}
parentMethod = (child_name) => {
//接收子组件传递的参数
console.log('子组件传递的值是:', child_name)
}
render() {
return <div className=''>
<Child name={this.state.name} ref={this.myRef} parentMethod={this.parentMethod}></Child>
</div>
}
}
export default withRouter(Parent);
---------------------------------------------------
// 子组件
import React from 'react';
export default class Child extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
//调用父组件的方法并传递参数
this.props.parentMethod('child_name')
}
render() {
return <div className=''>
<div>子组件content</div>
</div>
}
}
3. 兄弟组件
- 传参
- 通过共同的父节点来充当参数传递的中介
- 基于发布订阅模式:eventEmitter
//事件总线
import { EventEmitter } from 'events';
export default new EventEmitter();
---------------------------------------------------
// 子组件1
import React from 'react';
import event from './events';//引入创建的EventEmitter实例
export default class Child1 extends React.Component{
constructor(props){
super(props);
this.state={
name: 'child1'
}
}
componentDidMount() {
//发送事件
event.emit('my_event', this.state.name)//child2接收不到
}
handleClick = () => {
//发送事件
event.emit('my_event', this.state.name)//child2可以接收到
}
render() {
return <div className=''>
<div onClick={this.handleClick}>子组件1的content</div>
</div>
}
}
---------------------------------------------------
// 子组件2
import React from 'react';
import event from './events';
export default class Child2 extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
event.addListener('my_event', msg => {
console.log('接收到的来自child1的参数是:', msg)
})
}
render() {
return <div className=''>
<div>子组件2的content</div>
</div>
}
}
- 状态管理库(这里使用mobx)
//store
import { observable, action, decorate } from 'mobx';
export default class GlobalStore {
constructor(rootStore) {
this.rootStore = rootStore;
this.state = observable({
info: ''
});
}
// update actions
updateStore(key, data) {
this.state[key] = data;
}
}
decorate(GlobalStore, {
updateStore: action,
})
---------------------------------------------------
// 子组件1
import React from 'react';
import { observer, inject } from 'mobx-react';
class Child1 extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
//改变store中的state
this.props.globalStore.updateStore('info', 'change from child1');
}
render() {
return <div className=''>
<div>子组件1的content</div>
</div>
}
}
export default inject('globalStore')(
observer(Child1)
)
---------------------------------------------------
// 子组件2
import React from 'react';
import { observer, inject } from 'mobx-react';
class Child2 extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
//访问的store中的参数
console.log('this.props.store:', this.props.globalStore.state.info)
}
render() {
return <div className=''>
<div>子组件2的content</div>
</div>
}
}
export default inject('globalStore')(
observer(Child2)
)
4. 爷孙组件
- 传参:context(以下为demo,官网也有具体用法)、eventEmitter(参考3)
//公共context
import React from 'react';
const ThemeContext = React.createContext('default_value');
export default ThemeContext;
---------------------------------------------------
// 父组件
import React from 'react';
import { withRouter } from 'react-router-dom';
import Child from './child';
import ThemeContext from './themeContext';
class Parent4 extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
}
render() {
return <div className=''>
<ThemeContext.Provider value='sklnfdnsjfnkdnfkndf'>
<Child></Child>
</ThemeContext.Provider>
</div>
}
}
export default withRouter(Parent4);
---------------------------------------------------
// 孙组件
import React from 'react';
import ThemeContext from './themeContext';
export default class GrandSon extends React.Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount() {
//访问到爷爷组件中传递的参数
console.log('this.context...', this.context)
}
render() {
return <div className=''>
</div>
}
}
GrandSon.contextType=ThemeContext;//将contextType挂在class上,有助于在class的任何地方都能访问到this.context
步骤:
- 创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。
const ThemeContext = React.createContext('default_value');
- 每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。
<ThemeContext.Provider value='sklnfdnsjfnkdnfkndf'>
<Child></Child>
</ThemeContext.Provider>
- 利用this.context访问到根组件传递的参数
希望大家能持续关注哦,留一些个人信息方便大家找到我哦。github
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。