React组件间通信

组件间通信

1.父组件中放入子组件,将自身属性与方法传给子组件,子组件即父组件的一部分,所以只要父组件重新render,子组件也必定重新render.
2.子组件this.props接收父组件传过来的属性与方法,this.props.add调用父组件方法,this.setState为父组件中的state.

import React, { Component } from 'react';
import { render } from 'react-dom';
import Example from '../components/Example.js';

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            a: 1
        };
    }
    add = () => {
        this.setState({
            a: this.state.a + 1
        });
    }
    render() {
        return (
            <div>
                <div>
                    { this.state.a }
                    <Example a = { this.state.a } add={ this.add } />
                </div>
            </div>
        );
    }
}

render(<App />, document.getElementById('root'));
import React, { Component } from 'react';
import { render } from 'react-dom';

class Example extends Component {
    constructor(props) {
        super(props);
        this.state = {
            a: 10
        };
    }
    componentWillReceiveProps(nextProps) {
        this.setState({
            a: nextProps.a
        });
    }
    add = () => {
        this.setState({
            a: this.state.a + 1
        });
    }
    render() {
        return (
            <div>
                <p>父组件: { this.props.a }</p>
                <p>子组件: { this.state.a }</p>
                <button onClick={ this.add }>调用子组件自己的add方法</button>
                <button onClick={ this.props.add }>调用父组件add方法</button>
            </div>
        );
    }
}

export default Example;

父组件向子组件通信

React数据流动是单向的,父组件向子组件的通信也是最常见的方式.
父组件通过props向子组件传递需要的信息.

import React, { Component } from 'react';
import { render } from 'react-dom';
import ListTitle from '../components/ListTitle.js';
import ListItem from '../components/listItem.js';

class List extends Component {
    render() {
        let title = '父组件向子组件通信';
        let list = [1, 2, 3, 4, 5];

        return (
            <div>
                <ListTitle title={ title } />
                <ul>
                    {
                        list.map((item, index) => {
                            return (
                                <ListItem key={ index } value={ item } />
                            )
                        })
                    }
                </ul>
            </div>
        );
    }
}

render(<List />, document.getElementById('root'));

子组件向父组件通信

setState一般与回调函数均会成对出现,这是因为回调函数即是转换内部状态时的函数传统.
子组件使用this.props.fun调用父组件的函数,函数中一般会setState,触发父组件render,同时子组件也会render

    onItemChange = (item) => {
        const { list } = this.state;

        this.setState({
            list: list.map((prevItem) => {
                return {
                    text: prevItem.text,
                    checked: prevItem.text === item.text ? !prevItem.checked : prevItem.checked
                }
            })
        });
    }
    onTitleChange = () => {
        this.setState({
            title: '利用回掉函数,子组件向父组件通信'
        })
    }

跨级组件通信

当需要让子组件跨级访问信息时,我们可以像之前说的方法那样向更高级别的组件层层传递props.
在React中,我们可以使用context来实现跨级父子组件间的通信.
我们并没有给ListItem传递props,而是在父组件定义了ChildContext,这样从这一层开始的子组件都可以拿到定义的context,例如这里的txt.
不过React官方并不建议大量使用context,因为它可以减少逐层传递,但当组件结构复杂时,我们并不知道context是从哪里传过来的.
Context就像一个全局变量一样,而全局变量正是导致应用走向混乱的罪魁祸首之一,给组件带来了外部依赖的副作用.
使用context比较好的场景是真正意义上的全局信息且不会更改,例如界面主题,用户信息等.
1.父组件

static childContextTypes = {
    txt: React.PropTypes.string
};
getChildContext() {
    return {
        txt: 'aaaa'
    };
}

2.子组件

static contextTypes = {
    txt: React.PropTypes.string
};
<span>span: { this.context.txt }</span>

没有嵌套关系的组件通信

1.没有嵌套关系的,那只能通过可以影响全局的一些机制去考虑,自定义事件机制不失为一种上佳的方法.
2.在componentDidMount事件中,如果组件完成挂载,再订阅事件.
当组件卸载的时候,在componentWillUnmount事件中取消事件的订阅.

    原文作者:蛋白
    原文地址: https://segmentfault.com/a/1190000010336868
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞