方法:(通过props来传值,这种应用,很多时候我们某个组件在不同的地方用到,但是就只是内容不一样,这样在调用组件就是父组件的时候给各自自己的值就好)
父组件:
import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
export default class index extends Component {
render() {
return (
)
}
}
子组件:
import React, { Component } from 'react'
export default class index extends Component {
render() {
return (
{this.props.nameall}
)
}
}
方法:将父组件的改变状态的方法传入子组件的props,绑定给子组件中的某些触发事件譬如按钮的点击,输入框输入等等,得到子组件的值或状态或动作,再调用父组件的方法得到子组件中的值。【props接受并执行】
子组件:
import React, { Component } from 'react'
export default class index extends Component {
//此方法改变父元素的背景色
setData = () => {
//此函数必须和父组件中的函数一样,将要改成什么颜色传给父组件,来改变父元素的值
//接收并执行此函数
this.props.changeColor("green")
}
render() {
return (
父元素的颜色====={this.props.bgColor}
)
}
}
父组件:
import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
export default class index extends Component {
state={
bgColor:"#999"
}
//修改在父组件中修改哦哦【注意】
baChange=(color)=>{
console.log(color)
this.setState({
bgColor:color
})
}
render() {
return (
{/* changeColor为父组件传给子组件传值方法 */}
{this.baChange(color)}}/>
)
}
}
方法1:bus
React 中组件与通过 bus 、 bus.emit(‘xx’,{data})、 bus.on(‘xx’,data=>{}) 来传值;传值的组件用 bus.emit(‘xx’,{data})传值,接收值的组件用 bus.on(‘xx’,data=>{}) 来接收传来的值
bus.js代码:
import {EventEmitter} from 'events'
const bus = new EventEmitter()
export default bus;
子组件1:
import React, { Component } from 'react'
import bus from '../utis/bus' /*一定要导入bus */
export default class Brother1 extends Component {
// dom节点渲染完毕
componentDidMount(){
//接收brother2传来的值
bus.on('sendVal',data=>{
console.log(data)
})
}
//向brother2传值
sendValueBrother2 = ()=>{
bus.emit('sendValue',{
name:'赵敏',
age:600
})
}
render() {
return (
兄弟1组件
)
}
}
子组件2:
import React, { Component } from 'react'
import bus from '../utis/bus' /*一定要导入bus */
export default class Brother2 extends Component {
//向brother1传值
sendValueBrother1 = ()=>{
bus.emit('sendVal',{
name:'周芷若',
age:600
})
}
// dom节点渲染完毕
componentDidMount(){
//接收brother1传来的值
bus.on('sendValue',data =>{
console.log(data)
})
}
render() {
return (
兄弟2组件
)
}
}
父组件:
import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
import Children from '../../company/oo'
export default class index extends Component {
render() {
return (
{/* 子组件1 */}
{/* 子组件2 */}
)
}
}
方法2:事实上是将一些共同的状态存入一个更高的组件中存放着,从这个地方操作值和调用值【类似于子传父】
子组件1:
import React, { Component } from 'react'
export default class index extends Component {
changefun=()=>{
this.props.changeChild2Color("green");
}
render() {
return (
子组件1
)
}
}
子组件2:
import React, { Component } from 'react'
export default class oo extends Component {
render() {
return (
{/* 从父元素获取自己的背景色 */}
子组件2的背景:{this.props.bgColor}
)
}
}
父组件:
import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
import Children from '../../company/oo'
export default class index extends Component {
state={
child2color:"#999",
}
changcolor2=(color)=>{
this.setState({
child2color:color
})
}
render() {
return (
{/* 子组件1 */}
{this.changcolor2(color)}}/>
{/* 子组件2 */}
)
}
}
4.跨级组件
所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:
对于第一种方式,如果父组件结构较深,那么中间的每一层组件都要去传递 props,增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的。不过这种方式也是可行的,当组件层次在三层以内可以采用这种方式,当组件嵌套过深时,采用这种方式就需要斟酌了。
使用 context 是另一种可行的方式,context 相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。
使用 context 也很简单,需要满足两个条件:
在使用 context 时,需要注意:
父组件需要声明自己支持 context,并提供 context 中属性的 PropTypes
子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes
父组件需提供一个 getChildContext 函数,以返回一个初始的 context 对象
如果组件中使用构造函数(constructor),还需要在构造函数中传入第二个参数 context,并在 super 调用父类构造函数是传入 context,否则会造成组件中无法使用 context。
如果要改变context对象,需要将其与父组件的state或者props相关联,通过改变该父组件的state或者props来改变context。在父组件的 state 或 props 变化时,会自动调用 getChildContext 方法,返回新的 context 对象,而后子组件进行相应的渲染。
父组件:home.js
import React, { Component } from 'react';
//父组件需要声明自己支持 context,并提供 context 中属性的 PropTypes
import PropTypes from "prop-types";
//引入子组件
import Sub from "../../company/sub";
export default class index extends Component {
//上级组件要声明自己支持 context,并提供一个函数来返回相应的 context 对象
// 父组件声明自己支持 context
static childContextTypes = {
color: PropTypes.string,
callback: PropTypes.func,
}
//父组件需提供一个 getChildContext 函数,以返回一个初始的 context 对象
// 父组件提供一个函数,用来返回相应的 context 对象
getChildContext() {
return {
color: "red",
callback: this.callback.bind(this)
}
}
callback(msg) {
console.log(msg)
}
render() {
return (
);
}
}
子组件:sub.js
import React from "react";
import SubSub from "./subsub";
const Sub = (props) =>{
return(
);
}
export default Sub;
子组件中的子组件:subsub.js
import React, { Component } from "react";
//子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes
import PropTypes from "prop-types";
export default class SubSub extends Component {
// 子组件声明自己需要使用 context
static contextTypes = {
color: PropTypes.string,
callback: PropTypes.func,
}
render() {
console.log(this.context)
//方法一:
const style = { color: this.context.color }
console.log(style);//打印得到
//方法二:
// let {style}=this.context.color;
// console.log(style);//打印不到
const cb = (msg) => {
console.log(msg)
return () => {
this.context.callback(msg);
}
}
return (
SUBSUB
);
}
}
5.非嵌套组件
就是没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。对于非嵌套组件,可以采用下面两种方式:
第一种方式所使用的context对象类似一个全局变量,有可能会造成全局污染。[不推荐]
先安装:
npm install event -S
组件结构: App组件为根组件,根组件里面有两个兄弟组件,foo,boo, 用于在foo和boo组件进行通信的Event服务.下面实现foo组件与boo组件之间的通信
event.js
//向外提供一个事件对象
import { EventEmitter } from "events";
export default new EventEmitter();
home.js
import React, { Component } from 'react';
import Foo from "../foo";
import Boo from "../boo";
export default class App extends Component{
render(){
return(
Welcome to React
);
}
}
boo.js
import React,{ Component } from "react";
import emitter from "../utis/event"
export default class Boo extends Component{
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
emitter.emit('callMe', 'Hello');
}
render() {
return (
);
}
}
foo.js
import React,{ Component } from "react";
import emitter from "../utis/event"
export default class Foo extends Component{
constructor() {
super();
}
componentDidMount() {
this.eventEmitter = emitter.on('callMe', (msg) => {
alert(msg);
});
}
componentWillUnmount() {
emitter.removeListener(this.eventEmitter);
}
render() {
return (
Parent Component
);
}
}