• React兄弟、父子元素之间的通信


    React兄弟、父子元素之间的通信

    React元素之间的通信主要由下面几种方式 
    1、 Redux 
    2、 EventEmitter 
    3、 通过props进行通信(需要有嵌套关系)

    子元素到父元素

    父子元素之间的通信主要靠props,这个方法既简单,又好用,所以可以使用这种方法的时候就直接用好了。 
    首先有这样的一个React DOM结构:

    <div className="passage">
         <NavBar   />
         <Passage />
    </div>

    渲染外层的div元素的时候,需要进行两个子组件的渲染,其中Passage组件的加载内容取决于NavBar当前的内容或者被点击后的内容,这里可以首先实现父元素和NavBar之间的通信过程,设置一个句柄,来帮助进行通信。

    constructor (props) {
            super(props);
            this.state = {
                currentPassage: ""
            }
            this.refreshCurrentPassage = this.refreshCurrentPassage.bind(this);
        }
    
        refreshCurrentPassage(cp) {
            this.setState({
                currentPassage: cp
            });
        }

    上面的refreshCurrentPassage函数是这个通信过程的关键,我们将这个函数绑定当前父元素的this对象,并且将这个函数通过props传递给子元素:

     render() {
            return (
                <div className="passage">
                    <NavBar  refreshCurrentPassage={this.refreshCurrentPassage} />
                    <Passage currentPassage={this.state.currentPassage}/>
                </div>
            );
        }

    子元素在其生命周期的componentDidMount阶段通过ajax获取当前页信息并且调用这个函数,将消息传递给父元素,这里需要注意React的生命周期,componentDidMount在官方给出的解释是:

    Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.

    注意是在初始化渲染之后执行一次的。如果你还有其他特殊需求的话可以在其他阶段来调用这个函数。

    class NavUl extends React.Component {
        constructor (props) {
            super(props);
            this.state = {
                passage: []
            }
        }
    
        componentDidMount() {
        //在ajax请求成功之后调用一次更新父元素状态的函数,来完成一次父子元素之间的通信
            $.ajax({
                url: "../resources/data/passage.json",
                success: (data) => {
                    this.setState({
                        passage: data.passages
                    });
                    this.props.refreshCurrentPassage(data.passages[0].passageName);
                }、
            });
        }
    
        render() {
            let liArray = [];
            this.state.passage.forEach((value,index) => {
                let liEle = <li key={value.passageName.toString()}>
                    <a>
                        {value.passageName}({value.letterNum})&nbsp;author:{value.author}
                    </a>
                </li>
                liArray.push(liEle);
            });
            return (
                <ul>
                    {liArray}
                </ul>
            )
        }
    }
    
    class NavBar extends React.Component {
        constructor (props) {
            super(props);
        }
    
        render() {
            return (
                <nav>
                    <NavUl refreshCurrentPassage={this.props.refreshCurrentPassage}/>
                </nav>
            );
        }
    }

    父元素到子元素

    父元素到子元素的状态通信更加简单了,可以直接使用props来进行传递。

    //父元素的render函数
        render() {
            return (
                <div className="passage">
                    <NavBar  refreshCurrentPassage={this.refreshCurrentPassage} />
                    <Passage currentPassage={this.state.currentPassage}/>
                </div>
            );
        }

    通过将自己的state的currentPassage属性传递给子元素的一个属性,也就是props对象,来告诉子元素加载某个模块。

    class Passage extends React.Component {
        constructor (props) {
            super(props);
    
            this.state = {
                passage: ""
            }
    
        }
    //子元素通过自己的this.props对象来进行访问,可以直接得到父元素传递的消息
        componentWillReceiveProps (nextProps) {
            let passageName = nextProps.currentPassage;
            passageName = passageName.toLowerCase().replace(" ", "");
            $.ajax({
                url: "../resources/data/" + passageName + ".json",
                success: (data) => {
                    this.setState({
                        passage: data.passageContent
                    });
                }
            });
        }
    
        render() {
            return (
                <article>
                    <p>
                        {this.state.passage}
                    </p>
                </article>
            );
        }
    }

    兄弟元素之间

    上面的两个部分组合起来刚好就完成了兄弟元素之前的通信,其中一个子元素通过调用父元素传递过来的函数this.props.refreshCurrentPassage来修改父元素状态,然后在父元素状态修改之后,另外一个子元素的this.props会发生变化,从而触发重新渲染。这里需要注意的是React组件的声明周期,父元素到子元素通信由于可能需要多次渲染,所以使用了声明周期中的componentWillReceiveProps阶段来进行内容加载。在官方文档中是这么介绍这个阶段的:

    Invoked when a component is receiving new props. This method is not called for the initial render.

    也就是在一个组件接收了新的属性(props)触发的,这个方法不会在初始化渲染的时候触发。并且这个阶段还可以访问修改前的props对象。

  • 相关阅读:
    C学习笔记——字符串操作
    抓取网站特定内容后直接入mysql库
    C语言笔记——时间运算
    SCP链接方式
    C学习笔记——数组
    免费HTTP数据抓包Fiddler2[4.6.1.2]以及显示中文包内容的方法
    近期要研究的jquery插件
    Always 英文技术网站一
    silverlight工具下载网址
    英文网站参照1
  • 原文地址:https://www.cnblogs.com/Michelle20180227/p/9105585.html
Copyright © 2020-2023  润新知