1.父子组件通信方式
//父组件
import Home from "./home/home.js";
class element extends Component {
constructor(props) {
super(props);
this.state = {
msg: "我是父组件的数据",
};
}
render() {
return (
<div>
<Home msg={this.state.msg} />//子组件
</div>
);
}
}
//子组件
class Home extends Component {
constructor(props) {
super(props);
console.log(this.props);//接收父组件传来的数据
}
render() {
return (
<div>
<h1 className="red">{this.props.msg}</h1>
</div>
);
}
}
2.子组件传父组件(使用回调函数)
//父组件
import Home from "./home/home.js";
import React, { Component } from "react";
class element extends Component {
constructor(props) {
super(props);
this.state = {
msg: "我是父组件的数据",
};
}
setMsg = (pyload) => {
console.log("接收到的数据",pyload);
};
render() {
return (
<div> //这里传数据需要用到回调函数
<Home fun={(pyload)=>{this.setMsg(pyload)}} />
<h2>Good to see you here.</h2>
</div>
);
}
}
//子组件
import React, { Component } from "react";
class Home extends Component {
constructor(props) {
super(props);
console.log(this.props);
}
setMsg=()=>{
this.props.fun("我是子组件数据")
};
render() {
return (
<div>
<button onClick={this.setMsg}>按钮</button>
</div>
);
}
}
3.使用上下文createContext (祖代传与后代的方法)
注意! React.createContext() 不要重复引入 不然会导致获取不了数据
后代想要修改值 不能直接修改,因为数据是单向流的,用回调函数方式通知祖代修改数据
需要在祖代传入一个修改数据的函数即可
//这是后代组件
import React, { Component } from "react";
import { Consumer } from "../context.js"; //那个后代需要祖代数据 就要引入Consumer
class about extends Component {
render() {
return (
<div>
<Consumer>
{(value) => {
return <div>我是后代组件:{value.msg}<button onClick={value.func.bind(this,2)} >修改祖代数据</button></div> //这里一定要调用bind方法
//不然会频繁触发且报错
}}
</Consumer>
</div>
);
}
}
export default about;
//这是祖代组件
import Home from "./home/home.js"; //第一层后代
import React, { Component } from "react";
import {Provider} from "./context.js"
class element extends Component {
constructor(props) {
super(props);
this.state = {
msg: "我是父组件的数据",
};
}
setMsg=(pyload)=>{//修改方法
console.log(pyload);
this.setState({
msg:pyload
});
render() {
return (
<div>
<Provider value={{ msg: this.state.msg,func:(pyload)=>{this.setMsg(pyload)}}}> //想要修改数据可以引入函数
<Home />//格式与上面后代一致,只是引入组件方式不一样
</Provider>
</div>
);
}
}
export default element;
//context.js
import React from 'react'
const ThemeContext = React.createContext()
export const Provider = ThemeContext.Provider
export const Consumer = ThemeContext.Consumer
4.兄弟组件传值
也可以使用createContext进行传值
让父组件 作为中间件,兄弟之间通过父组件进行传值 bro1=>father=>bro2 bro2=>father=>bro1
//父组件
import "./App.css";
import Home from "./home/home.js";
import Home2 from "./home/home2.js";
import React, { Component } from "react";
import { Provider } from "./context.js";
class element extends Component {
constructor(props) {
super(props);
this.state = {
home1: "我是home1数据",
home2: "我是home2数据",
};
}
setMsg = (pyload) => {
console.log(pyload);
this.setState({
msg: pyload,
});
};
homefun1 = (pyload) => {
console.log(`我是home1${pyload}`);
this.setState({
home2: pyload,
});
};
homefun2 = (pyload) => {
console.log(`我是home2${pyload}`);
this.setState({
home1: pyload,
});
};
render() {
let {home1,home2}=this.state
let {homefun1,homefun2}=this
return (
<div>
<Provider
value={{home1,home2,homefun1,homefun2}}
>
<Home />
<Home2/>
</Provider>
</div>
);
}
}
export default element;
//子组件1
import './home.css'
import React, { Component } from "react";
import About from "../about/about.js";
import { Consumer } from "../context.js";
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<About></About>
<Consumer>
{(value) => {
return <div>我是home1:{value.home1}<button onClick={value.homefun1.bind(this,"home1数据")} >修改home2数据</button></div>
}}
</Consumer>
</div>
);
}
}
export default Home
//子组件2
import React, { Component } from 'react';
import { Consumer } from "../context.js";
class home2 extends Component {
render() {
return (
<div>
<Consumer>
{(value) => {
return <div>我是home2:{value.home2}<button onClick={value.homefun2.bind(this,"home2数据")} >修改home1数据</button></div>
}}
</Consumer>
</div>
);
}
}
export default home2;
5.events(跨组件通信)
需要下载
npm install events -S
addListener("与emit名称一致才会触发",(res)=>{"这里是回调函数,res是数据"})
emit("自定义事件名称","发送的数据")
//组件销毁的时候一定要销毁监听 不然容易导致内存溢出
removeAllListeners("需要销毁的名称")
//先封装一个eventbus.js 文件
import {EventEmitter} from 'events'
export default new EventEmitter;
//在需要的地方引入即可
//home1.js
import "./home.css";
import React, { Component } from "react";
import About from "../about/about.js";
import Bus from "../eventbus.js";
class Home extends Component {
constructor(props) {
super(props);
this.state = {
bus: "我是home1的数据",
};
}
componentDidMount(){//在生命周期挂着时,开启监听
Bus.addListener("changeSiblingsData", (msg) => {
console.log(this);
this.setState({
bus: msg,
});
console.log(msg);
});
}
componentWillUnmount() {//注意在销毁函数 销毁监听
console.log("我被销毁了");
Bus.removeAllListeners("changeSiblingsData");
}
render() {
return (
<div>
<About></About>
我是home1 {this.state.bus}
</div>
);
}
}
export default Home;
//在home2.js
import React, { Component } from "react";
import Bus from "../eventbus.js";
class home2 extends Component {
constructor(props) {
super(props);
this.state = {
bus: "我是home2的数据",
};
}
emit = () => {
let msg = "我是home2数据";
//发布订阅
Bus.emit("changeSiblingsData", msg);
};
componentDidMount() {
console.log(Bus);
//这里自己也可以监听自己的
Bus.addListener("changeSiblingsData", (msg) => {
console.log(this);
this.setState({
bus: msg,
});
console.log(msg);
});
}
componentWillUnmount() {
console.log("我被销毁了");
Bus.removeAllListeners("changeSiblingsData");
}
render() {
return (
<div id="example">
我是home2{this.state.bus}
<button onClick={this.emit}>发送数据</button>
</div>
);
}
}
export default home2;