React 组件传值
- 父传子
- 父组件
导入自组件
import GroupTable from "../View/Table"
<GroupTable columns={this.state.columns} data={this.state.data}></GroupTable>
- 子组件
export default class GroupTable extends Component{
constructor(props){
super(props);
this.state = {
columns: [],
data: []
}
}
handleSort(data){
console.log('自定义');
console.log(data.column);
console.log(data.prop);
console.log(data.order);
}
render() {
- [ 当前this.props 是用来接收父组件传递的值的]
- let {columns,data}= this.props
return (
<Table
style={{width: '100%'}}
columns={columns}
data={data}
border={true}
onSortChange={this.handleSort.bind(this)}
/>
)
}
}
2.子传父
- 父组件
通过向自组件传递一个方法 自组件执行父组件的方法将参数传递过来
<GroupTable getChild={this.getChildren} columns={this.state.columns}
data={this.state.data}></GroupTable>
- 子组件
import React, { Component } from 'react';
import { Table } from 'element-react';
export default class GroupTable extends Component{
constructor(props){
super(props);
this.state = {
columns: [],
data: []
}
}
handleSort(data){
console.log('自定义');
console.log(data.column);
console.log(data.prop);
console.log(data.order);
}
1. [ 子组件执行父组件的方法将值传递过去]
rowClick=(row, column, cell, event)=>{
this.props.getChild(row)
}
render() {
console.log(this.props)
let {columns,data}= this.props
return (
<Table
style={{width: '100%'}}
columns={columns}
data={data}
border={true}
onSortChange={this.handleSort.bind(this)}
onCellClick={this.rowClick}
/>
)
}
}
3.兄弟传值
- 兄弟组件1 发布组件
兄弟组件传值使用一个插件 pubsub-js
通过发布和订阅实现组件间的数据流动
通过当前组件执行方法 将数据发送出去
import React, { Component } from 'react';
import Pubsub from 'pubsub-js'
export default class Brother extends Component{
constructor(props){
super(props)
}
click=()=>{
Pubsub.publish('username','sadksajdkajs')
}
render(){
return(
<div>
<button onClick={this.click}>点击发布</button>
</div>
)
}
}
- 兄弟组件2
当前组件通过在生命周期里面执行方法接收传递过来的数据
import React, { Component } from 'react';
import { Table } from 'element-react';
import Pubsub from 'pubsub-js'
export default class GroupTable extends Component{
constructor(props){
super(props);
this.state = {
columns: [],
data: []
}
}
render() {
console.log(this.props)
let {columns,data}= this.props
return (
<Table
style={{width: '100%'}}
columns={columns}
data={data}
border={true}
/>
)
}
componentDidMount(){
Pubsub.subscribe('username',(msg,data)=>{
console.log(msg,data) 前者是键值 后者是传递过来的数据
})
}
}
4.context 嵌套多层组件传值
/* 使用context 多层组件传值
父组件需要声明自己支持 context,并提供 context 中属性的 PropTypes
子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes
父组件需提供一个 getChildContext 函数,以返回一个初始的 context 对象
*/
爷爷组件
class RouterGroup extends Component {
// 父组件声明自己支持 context
constructor(props){
super(props)
this.state={
msg:'默认值'
}
} 定义一个childContextType 向孙子组件传值
static childContextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
// 父组件提供一个函数getChildContext,用来返回相应的 context 对象
getChildContext(){
return{
color:"red",
callback:this.callback.bind(this)
}
}
callback=(msg)=>{
console.log(msg)
this.setState({
msg:msg
})
}
render() {
return (
<div>
当前是测试页面首页========
<Child></Child>
当前展示的是孙子组件传的值===={this.state.msg}
</div>
);
}
}
export default RouterGroup;
/* 嵌套多层父子组件传值*/
子组件过度
function Child(props){
return <div>
我是子组件接收当前传递的值
<ChildChild></ChildChild>
</div>
}
/* 孙子组件 */
class ChildChild extends Component{
constructor(props){
super(props)
}
// 子组件声明自己需要使用 contextTypes 接收爷爷组件传递的值
static contextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
//孙子组件自己定义的方法用来当点击某个事件的时候向爷爷组件传值
sun_father=()=>{
console.log(this)
return this.context.callback("我是孙子组件的值")
}
render(){
return (<div>
我是孙子组件接收当前传递的值===={this.context.color}
<button onClick={this.sun_father}>向爷爷组件传值</button>
//this.context.callback 如果我们在dom渲染的时候直接调这个方法
不可以在爷爷组件修改值 因为在render渲染过程中我们不能直接修改state或props的值
</div>)
}
}
重点。。。。。。。
我们不应该也不能直接改变 context 对象中的属性,要想改变 context 对象,
只有让其和父组件的 state 或者 props 进行关联,在父组件的 state 或 props 变化时,
会自动调用 getChildContext 方法,返回新的 context 对象,而后子组件进行相应的渲染。
如果 子组件要改变传向父组件的值我们需要先向爷爷组件传递值在他改变之后再向孙子组件传递
context 同样可以应在无状态组件上,只需将 context 作为第二个参数传入:
import React,{ Component } from "react";
import PropTypes from "prop-types";
const SubSub = (props,context) => {
const style = { color:context.color }
const cb = (msg) => {
return () => {
context.callback(msg);
}
}
return(
<div style = { style }>
SUBSUB
<button onClick = { cb("我胡汉三又回来了!") }>点击我</button>
</div>
);
}
SubSub.contextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
export default SubSub;
5.非嵌套组件传值
父组件为公共组件
render() {
return (
<div>
当前是测试页面首页========
<Child></Child>
当前展示的是孙子组件传的值===={this.state.msg}
<button onClick={this.changeColor}>爷爷组件点击</button>
{/* <Audio></Audio> */}
<ChildA/>
<ChildB/>
</div>
);
}
需要下载一个公共包
npm install events --save
下载一个专用的公共js包
import { EventEmitter } from "events";
export default new EventEmitter();
兄弟组件A 当前组件是发送数据组件
在每一个兄弟组件里面引入公共包
class ChildA extends Component{
constructor(props){
super(props)
this.state={
msg:'111111'
}
}
render(){
const cb = (msg) => {
return () => {
console.log(msg)
// 触发自定义事件
emitter.emit("callMe",msg)
}
}
return(
<div>
兄弟组件A
<button onClick={cb('触发事件传递的值')}>兄弟组件A</button>
</div>
)
}
}
兄弟组件B 当前组件是接收组件 需要在生命周期里面监听事件 还要销毁监听事件
class ChildB extends Component{
constructor(props){
super(props)
this.state={
msg:'111111'
}
}
componentDidMount(){
// 声明一个自定义事件
// 在组件装载完成以后
this.eventEmitter = emitter.addListener("callMe",(msg)=>{
this.setState({
msg
})
});
}
// 组件销毁前移除事件监听
componentWillUnmount(){
emitter.removeListener(this.eventEmitter);
}
render(){
return <div>
兄弟组件B====
{this.state.msg}
</div>
}
}