react基础组件几种通信方法
1.父子组件通信
父组件向子组件通信:使用 props
子组件向父组件通信:使用 props 回调
本文使用React 16.8 的新增特性 Hook示例
// Parents父组件
// 使用 props val 传值
// 通过 emit自定义事件 childChange 接收子组件回调
import React, { useState } from 'react';
import ChildrenA from './ChildrenA';
function Parents(props) {
const [val, setVal] = useState('john')
const handleChange = (v) => { setVal(v) }
return (
<div>
这是ChildrenA emit的值:{val}
<ChildrenA val={val} childChange = { handleChange}></ChildrenA>
</div>
)
}
export default Parents
// ChildrenA子组件
// 通过 props.val 接收父组件传值
// 通过 emit自定义事件 props.childChange 传递给父组件
import React, { useState } from 'react';
function ChildrenA(props) {
const [val, setVal] = useState(props.val)
const changeVal = (e) =>{
setVal(e.target.value)
props.childChange(e.target.value)
}
return (
<div>
这是Parents props传递的值:{val}
<input type="text" value={val} onChange={changeVal}/>
</div>
)
}
export default ChildrenA
2.跨级组件间通信:
跨级组件通信,就是父组件向子组件、孙组件、或更深层的子孙组件通信。跨级组件通信可以采用下面两种方式:
2.1中间组件层层传递 props(多层嵌套不建议)
2.2使用 context 对象
App 组件,这里作为爷组件
import React from 'react';
import PropTypes from "prop-types";
import Parents from './views/main/Parents';
class App extends React.Component {
// 父组件声明自己支持 context
constructor() {
super();
this.state = {
msg: ''
}
}
static childContextTypes = {
color: PropTypes.string,
callback: PropTypes.func,
}
// 父组件提供一个函数,用来返回相应的 context 对象
getChildContext(){
return {
color: "red",
callback: this.callback.bind(this)
}
}
callback(val){
this.setState({msg: val})
console.log(val)
}
render() {
return (
<div className="App">
子集传值:{this.state.msg}
<Parents></Parents>
</div>
);
}
}
export
Parents 这里做子组件,可以理解为中间很多层
import React from 'react';
import ChildrenA from './ChildrenA';
function Parents() {
return (
<>
<ChildrenA/>
</>
)
}
export default Parents
ChildrenA 孙组件,可以理解为多层嵌套
import React from 'react';
import PropTypes from "prop-types";
class ChildrenA extends React.Component {
// 子组件声明自己需要使用 context
static contextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
cb (msg){
return () => {
this.context.callback(msg);
}
}
render() {
return (
<div style={{ color:this.context.color }}>
{this.context.color}
<button onClick = { this.cb("john!") }>点击我</button>
</div>
)
}
}
export default ChildrenA
3.非嵌套组件间通信:
3.1利用二者共同父组件的 context 对象进行通信
3.2使用自定义事件的方式(使用 events 包)
安装依赖包
npm install events --save
新建一个 ev.js,引入 events 包,并向外提供一个事件对象,供通信时使用:
import { EventEmitter } from "events";
export default new EventEmitter();
父级
import React from 'react';
import ChildrenA from './ChildrenA';
import ChildrenB from './ChildrenB';
function Parents() {
return (
<>
<ChildrenA/>
<ChildrenB/>
</>
)
}
export default Parents
子级A
import React from "react";
import emitter from "./ev"
export default class ChildrenA extends React.Component{
constructor(props) {
super(props);
this.state = {
msg:null,
};
}
componentDidMount(){
// 声明一个自定义事件
// 在组件装载完成以后
this.eventEmitter = emitter.addListener("callMe",(msg)=>{
this.setState({
msg
})
});
}
// 组件销毁前移除事件监听
componentWillUnmount(){
emitter.removeListener(this.eventEmitter);
}
render(){
return(
<div>
我是非嵌套 ChildrenA
<p>这是ChildrenB传的值:{ this.state.msg }</p>
</div>
);
}
}
子级B
import React from "react";
import emitter from "./ev"
export default class ChildrenB extends React.Component{
render(){
const cb = (msg) => {
return () => {
// 触发自定义事件
emitter.emit("callMe","Hello,john")
}
}
return(
<div>
我是非嵌套 ChildrenB
<button onClick = { cb("blue") }>点击我</button>
</div>
);
}
}
4.状态管理通信:
Redux 、MobX 、dvajs 等状态管理,这里不做介绍
这是一篇沉没于知识大海的博客; 每天进步一点点,记录成长点滴。–john