react中组件传值

文章详细介绍了React中组件间的通信方式,包括父组件通过props向子组件传递值,子组件通过回调函数向父组件传递值,以及非父子组件间的通信,如通过中间件(事件总线)和React的ContextAPI实现跨级组件的数据传递。此外,文中还提到了使用JSON.stringify和JSON.parse处理Context中的对象值问题。
摘要由CSDN通过智能技术生成

一,父传子

 在父组件中的子组件标签上属性,在子组件中用this.props.属性接收

父组件:

子组件:

二,子传父 

在父组件中的子组件标签上添加属性,属性值为一个函数方法,在子组件中通过this.props.属性传值。

父组件:

子组件:

三,非父子组件传值

方法1:子传父,父再传给子组件 (此方法适用于亲兄弟组件之间的传值,其他的亲戚组件用该方法较为繁琐,不推荐使用)

方法2:封装一个公共的方法,通过发布者-订阅者的模式。

封装common.js

var bus ={
    list:[],
    // 收集订阅
    sub(callback){
       this.list.push(callback)
    },
    // 调函数
    pub(val){
        this.list.forEach((item)=>{
            item && item(val)
        })
    }
}
export  default bus

two组件

import React from "react";
import bus from "./common";
export default class Two extends React.Component{
    
    constructor(){
        super();
        this.state={
            age:15,
            sex:'男'
        }
    }
    render(){
        return(
            <button onClick={()=>{
                bus.pub(this.state.sex)
            }}>点击2</button>
        )
    }
}

one组件

import bus from './common'
import React from "react";
import { OneOne } from './OneOne';
export default class One extends React.Component{
    constructor(){
        super();
        this.state ={
            num:2,
            age:'',
            sex:''
        }
    }
    componentDidMount(){
        this.init()
    }
    init(){
        bus.sub((val)=>{
            this.setState({
                sex:val
            })
        })
    }
   
    render(){
        return(
            <div>
              我是one组件你
              <OneOne numb={this.state.num} hand={this.handle}/>
              我是从oneone子组件传给父组件的年龄:{this.state.age}

              我是从兄弟Two组件传过来的性别:{this.state.sex}
            </div>
        )
    }
    handle=(val)=>{
        this.setState({
            age:val
        })
    }
}

方法3:

react官网提供的context方法(思路是先将其中一个组件修改值传到包裹两个组件state中,另一个要接收数据的组件从包裹它们的组件state中获取(和方法1有点类似)

1,使用react中提供createContext方法

export const Context = React.createContext(null)

2,用Context.Provider标签将两个要传值的非父子组件包裹起来

             <Context.Provider value={JSON.stringify(this.state)}>
                <div>
                    <One></One>
                    <Two changeInfo={this.changeDate} />
                </div>
            </Context.Provider>

3,用Context.Consumer标签将两个相互传值非父子组件的return包裹起来,注意:包裹标签里是一个函数,并用return将组件内容return出去

 

 此时,两个组件都能获取到包裹她们Context.Provider 标签value的值(注意,不知道是不是版本的原因,我这儿value是不能传对象的  所以我用json.stringify将它转为字符串,然后再接收的组件用json.parse取value值)。

 注意此时在two组件修改来自标签value上值时,你会发现控制台打印修改成功后的值,但页面却并未更新,因为你没有通过setState重新让render执行渲染,所以得加一个更改方法去更改包裹她们的组件state中的值

 

 完整代码如下:

father.js

import React from "react";
import One from './one';
import Two from './Two';
export const Context = React.createContext(null)
export default class Father extends React.Component {
    constructor(props){
        super(props);
        this.state={
            sex:'女',
            
        }
    }
    render() {
        return (
            <Context.Provider value={JSON.stringify(this.state)}>
                <div>
                    <One></One>
                    <Two changeInfo={this.changeDate} />
                </div>
            </Context.Provider>
        )
    }
    changeDate=(value)=>{
        this.setState({
            sex:value
        })
    }
}

one.js

import bus from './common'
import React from "react";
import { OneOne } from './OneOne';
import {Context} from './Father.js'

export default class One extends React.Component{
    constructor(){
        super();
        this.state ={
            num:2,
            age:'',
            sex:''
        }
    }
    // componentDidMount(){
    //     this.init()
    // }
    // init(){
    //     bus.sub((val)=>{
    //         this.setState({
    //             sex:val
    //         })
    //     })
    // }
   
    render(){
        return(
           <Context.Consumer>
            {(value)=>{
                value = JSON.parse(value)
                return <div>
                 我是one组件你
                 <OneOne numb={this.state.num} hand={this.handle}/>
                 我是从oneone子组件传给父组件的年龄:{this.state.age}
   
                 我是从兄弟Two组件传过来的性别:{value.sex}
               </div>
            }}
           </Context.Consumer>
        )
    }
    handle=(val)=>{
        this.setState({
            age:val
        })
    }
}

two组件

import React from "react";
// import bus from "./common";
// import Context from './Father'
import {Context} from './Father.js'

export default class Two extends React.Component{
    constructor(){
        super();
        this.state={
            age:15,
            sex:'男'
        }
    }
    render(){
        return(
           <Context.Consumer>
            {
                (value)=>{
                    value = JSON.parse(value)
                    return  <button onClick={()=>{
                        // bus.pub(this.state.sex)
                        this.props.changeInfo(this.state.sex)
                    }}>点击2</button>
                }
            }
           </Context.Consumer>
        )
    }
}

此时就实现了将two组件值通过点击按钮就传给one组件了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值