一:父子传值 (props传值)
- Child.js
import React from 'react'
export default function Child({userInfo}) {
return (
<div>
<h1>Child组件</h1>
<div>
姓名 ---- {userInfo.name}
年龄 ---- {userInfo.age}
性别 ---- {userInfo.gender}
</div>
</div>
)
}
- Parent.js
import React, { Component } from 'react'
import Child from './Child'
export default class Parents extends Component {
constructor() {
super()
this.state = {
obj: {
name: '张三',
age: 20,
gender: '男'
}
}
}
render() {
let { obj } = this.state;
return (
<div>
<h1>Parent组件</h1>
<Child userInfo={obj}></Child>
</div>
)
}
}
二:效果如下
子父传值(props传递函数)
- Child.js
import React from 'react'
export default function Child({userInfo,setUserInfo}) {
return (
<div>
<h1>Child组件</h1>
<div>
姓名 ---- {userInfo.name}
</div>
<button onClick={() => setUserInfo("李四")}>设置父组件的用户信息</button>
</div>
)
}
- Parent.js
import React, { Component } from 'react'
import Child from './Child'
export default class Parents extends Component {
constructor() {
super()
this.state = {
obj: {
name: '张三',
age: 20,
gender: '男'
}
}
}
getUserInfo = (name)=> {
let obj = {...this.state.obj}
obj.name = name;
this.setState({ obj })
}
render() {
let { obj } = this.state;
return (
<div>
<h1>Parent组件</h1>
<Child userInfo={obj} setUserInfo={this.getUserInfo}></Child>
</div>
)
}
}
效果图如下
三:跨级组件传值 context 相当于vue中的provide和Inject
- 新建context.js
import { createContext } from 'react'
export const context = createContext()
- 新建 GrandFather.js
import React, { Component } from 'react'
import Parents from './Parents'
import { context } from './context'
export default class GrandFather extends Component {
constructor() {
super()
this.state = {
obj: {
name: '张爷爷',
age: '60',
gender: '男'
}
}
}
render() {
return (
<div>
<h1>GrandFather组件</h1>
<context.Provider value={this.state.obj}>
<Parents></Parents>
</context.Provider>
</div>
)
}
}
- Child.js
// import React,{ useContext } from 'react'
import React from 'react'
import { context } from './context'
export default function Child() { // 函数组件使用useContext()
// const userInfo = useContext(context) // 第一种方式
return (
<div>
<h1>Child组件</h1>
{/* <div>
姓名: {userInfo.name}---
年龄: {userInfo.age}---
性别: {userInfo.gender}
</div> */}
{/* 第二种使用消费者模式,不推荐 */}
<context.Consumer>
{
userInfo => {
return (
<div>
姓名: {userInfo.name}---
年龄: {userInfo.age}---
性别: {userInfo.gender}
</div>
)
}
}
</context.Consumer>
</div>
)
}
- Father.js
import React, { Component } from 'react'
import Child from './Child'
import { context } from './context'
export default class Parents extends Component {
// static contextType = context // 第一种方式
constructor() {
super()
this.state = {
obj: {
name: '张爸爸',
age: 40,
gender: '男'
}
}
}
render() {
return (
<div>
<h1>Parent组件</h1>
<div>
姓名: {this.context.name}---
年龄: {this.context.age}---
性别: {this.context.gender}
</div>
<br/>
<Child></Child>
</div>
)
}
}
Parents.contextType = context // 第二种方式注入到组件的实例上
效果图如下
四:全局组件传值之 Nodejs中的events(发布订阅模式)
- 新建 bus.js
import { EventEmitter } from 'events'
export const bus = new EventEmitter() // 导出bus实例
- 新建child.js
import React from 'react'
import { bus as $bus } from './bus'
export default function Child() { // 函数组件使用useContext()
const sendMessage = ()=> {
console.log("触发");
let obj = {
name: '张孙子',
age: 20,
gender:'男'
}
$bus.emit("getMessage",obj)
}
return (
<div>
<h1>Child组件</h1>
<button onClick={ sendMessage }>发送消息给爷爷组件</button>
</div>
)
}
- 新建 GrandFather.js
import React, { Component } from 'react'
import Parents from './Parents'
import { bus as $bus } from './bus'
export default class GrandFather extends Component {
constructor() {
super()
this.state = {
obj: {
name: '张爷爷',
age: '60',
gender: '男'
}
}
}
componentDidMount() {
this.destory = $bus.addListener("getMessage",(res) => {
console.log("obj",res);
this.setState({
obj: res
})
})
}
componentWillUnmount() {
$bus.removeListener(this.destory);
}
render() {
let { name, age, gender } = this.state.obj
return (
<div>
<h1>GrandFather组件</h1>
<div>
姓名: {name}----
年龄: {age} ----
性别: {gender}
</div>
<Parents></Parents>
</div>
)
}
}
五:全局组件传值之 Pubsub.js(发布订阅模式)
发送消息:PubSub.publish(名称,参数)
订阅消息:PubSub.subscrib(名称,函数)
取消订阅:PubSub.unsubscrib(名称)
yarn add pubsub-js
- Child.js
import React from 'react'
import PubSub from 'pubsub-js';
export default function Child() { // 函数组件使用useContext()
const sendMessage = ()=> {
console.log("触发");
let obj = {
name: '张孙子',
age: 20,
gender:'男'
}
PubSub.publish("getMessage",obj)
}
return (
<div>
<h1>Child组件</h1>
<button onClick={ sendMessage }>发送消息给爷爷组件</button>
</div>
)
}
- GrandFather.js
import React, { Component } from 'react'
import Parents from './Parents'
import PubSub from 'pubsub-js';
export default class GrandFather extends Component {
constructor() {
super()
this.state = {
obj: {
name: '张爷爷',
age: '60',
gender: '男'
}
}
}
componentDidMount() {
this.destory = PubSub.subscribe("getMessage",(name,res) => { // 第二个参数函数里边的第一个是事件名 第二个参数才是真正的值
console.log("obj",res);
this.setState({
obj: res
})
})
}
componentWillUnmount() {
PubSub.unsubscribe(this.destory);
}
render() {
let { name, age, gender } = this.state.obj
return (
<div>
<h1>GrandFather组件</h1>
<div>
姓名: {name}----
年龄: {age} ----
性别: {gender}
</div>
<Parents></Parents>
</div>
)
}
}
效果图如下
六 ref
- Parenrts.js
import React, { Component } from 'react';
class Sub extends Component {
callback() {
return console.log('执行回调');
}
render() {
return <div>子组件</div>;
}
}
export default class Parents extends Component {
constructor(props) {
super(props);
this.sub = React.createRef();
}
handleOnClick() {
console.log("this.sub",this.sub.current.callback());
}
render() {
return (
<div>
<h1>Fathers组件</h1>
<button onClick={this.handleOnClick.bind(this)}>获取子组件的方法</button>
<Sub ref={this.sub}></Sub>
</div>
);
}
}
效果图如下:
七: redux这里我就不一一写了,前面写过这个redux,
一般我们dispatch触发一个action名字,然后交给reducer纯函数去处理action名字,并且返回一个新的state给store,在每次派发前,都需要通过 store.subscribe订阅监听store中的state,用户通过 store.getState().获取信息展示在页面上