React---基础4(组件通讯)

1.父传子

通过属性props传递:组件可以接受任意的 props(属性) ,包括原始值、React 元素,或者函数

2.子传父(不共用状态,各自管理各自的状态)

2.1 react导入库

npm install pubsub-js --save

2.2 react 页面引入pubsubjs

import PubSub from 'pubsub-js'

2.3 pubsubjs使用

发送消息:PubSub.publish(名称,参数)

订阅消息:PubSub.subscrib(名称,函数)

取消订阅:PubSub.unsubscrib(名称)

PS:pubsubjs源码及使用详情https://github.com/mroderick/PubSubJS

feater.js

import React from 'react';
import PubSub from 'pubsub-js';
import Child from './child';

class Feater extends React.Component {
    constructor(props) {
        super(props);
        this.state = {name:'',age:''}
    }
    componentDidMount() {
        // 订阅消息
        this.pubsub_token = PubSub.subscribe('PubSubMsg', (topic, msg) => {
            this.setState({
                name:msg.name,
                age:msg.age,
                sex:msg.sex
            })
        })
    }
    componentWillUnmount() {
        // 取消订阅
        PubSub.unsubscribe(this.pubsub_token)
    }
    render() {
        let props = {
            name: 'muzidigbig',
            age: 22
        }
        return (
            

使用pubsub事件订阅,组件间通信

{/* ...属性扩展 */} {this.state.name ? (

孩子传过来的值:{this.state.name}---{this.state.age}{this.state.sex ? ---{this.state.sex} : ''}

) : ''}
) } } export default Feater;

child.js

import React from 'react';
import PubSub from 'pubsub-js';

class Child extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
    }
    componentDidMount() {
        this.setState({
            name: this.props.name,
            age: this.props.age
        })
    }
    changeProps() {
        this.setState({
            name: "小红",
            age: "21",
            sex: "女"
        })
    }
    sendMsg() {
        // 发送消息
        PubSub.publish('PubSubMsg', this.state);
    }
    render() {
        return (
            

得到父亲传过来的值:{this.state.name}---{this.state.age}{this.state.sex ? ---{this.state.sex} : ''}

) } } export default Child;

3.状态提升(子公用父的状态)

通常情况下,同一个数据的变化需要几个不同的组件来反映。我们建议提升共享的状态到它们最近的祖先组件中

feater.js

import React from 'react';
import TemperatureInput from './TemperatureInput';
import BiolingVerdict from './BoilingVerdict';

class Calculator extends React.Component {
    constructor() {
        super();
        this.state = {
            temperature: '',
            scale: 'c'
        }
    }
    /** 
     * 摄氏度和华氏度之间转换
     * temperature: input值
     * convert: 单位
    */
    tryConvert(temperature, convert) {
        const input = parseFloat(temperature);
        if (Number.isNaN(input)) {
            return '';
        }
        const output = convert(input);
        const rounded = Math.round(output * 1000) / 1000;
        return rounded.toString();
    }
    // 两个函数在摄氏度和华氏度   start
    toCelsius(fahrenheit) {
        return (fahrenheit - 32) * 5 / 9;
    }

    toFahrenheit(celsius) {
        return (celsius * 9 / 5) + 32;
    }
    // 两个函数在摄氏度和华氏度   end

    // 获取input值并改变状态   start
    handleCelsiusChange(temperature) {
        this.setState({ scale: 'c', temperature });
    }

    handleFahrenheitChange(temperature) {
        this.setState({ scale: 'f', temperature })
    }
    // 获取input值并改变状态   end

    render() {
        const scale = this.state.scale;
        const temperature = this.state.temperature;
        const celsius = scale === 'f' ? this.tryConvert(temperature, this.toCelsius) : temperature;
        const fahrenheit = scale === 'c' ? this.tryConvert(temperature, this.toFahrenheit) : temperature;

        return (
            
{/* onTemperatureChange 传给子组件 */}
) } } export default Calculator;

child1.js

import React from 'react';

const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
}
class TemperatureInput extends React.Component {
    constructor(props) {
        super(props);
        console.log(this.props); // {scale: "c", temperature: "", onTemperatureChange: ƒ}
    }

    handleChange(e) {
        // 触发父组件onTemperatureChange
        this.props.onTemperatureChange(e.target.value);
    }

    render() {
        const temperature = this.props.temperature;
        const scale = this.props.scale;
        return (
            
Enter temperature in {scaleNames[scale]}
) } } export default TemperatureInput;

child2.js

import React from 'react';
class BoilingVerdict extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        let element;
        if (this.props.celsius >= 100) {
            element = 

The water would boil.{this.props.celsius}

; } else { element =

The water would not boil.{this.props.celsius}

; } return (
{element}
) } } export default BoilingVerdict;

 

你可能感兴趣的:(React,react,PubSub,组件通讯,props)