美文网首页
React组件之间的通信

React组件之间的通信

作者: 爱翔是我二媳妇 | 来源:发表于2018-07-17 17:17 被阅读0次

    父传子

    就是父组件传递值给子组件,这个一般用props就可以完成
    例如:

     render() {
            return(
                <div>
                    <h1>Simple TODO List</h1>
                    <AppendList appendList={ this.state.list }/>
                </div>
            )
        }
    
    console.log(this.props.appendList)
    

    通过以上方法即可访问。

    子传父

    问题引入
    现在我们需要实现一个功能,添加一个输入框的内容到一个list列表中,效果如下:

    功能图片

    我们把功能划分为三个组件,一个是添加功能append,也就是输入框和按钮,另一个是显示组件appendList,显示list的内容,还有一个是包含两种组件的父组件暂且取名为appendFather。

    • 首先我们编辑添加功能append:
    import React from "react"
    export default class Append extends React.Component{
       constructor(props){
           super(props);    
       }
       render() {
           return(
               <div>
                   <input type="text" />
                   <button value="添加" >添加</button>
               </div>
           )
       }
    }
    
    
    • 随后我们再编辑列表组件appendList:
    import React from "react"
    export default class AppendList extends React.Component{
    
        render() {
            return(
                    <ul>
                      <li></li>
                    </ul>
            )
        }
    }
    
    
    • 最后,我们需要在父组件存储list中的一些数据,以及将这两个子组件包含起来。
    import React from "react"
    import AppendList from "./appendList"
    import Append from "./append"
    export default class AppendFather extends React.Component{
        constructor(props){
            super(props);
            // 存储所需要的初始数据
            this.state={
                list:["苹果","梨子","香蕉"]
            }
        }
        render() {
            return(
                <div>
                    <h1>Simple TODO List</h1>
                    <Append />
                    <AppendList }/>
                </div>
            )
        }
    }
    

    现在我们的页面中还只是有一个输入框和按钮,数据并没有被渲染出来,我们需要将数据传递给AppendList这个组件(父传子),这里我们可以用到props。

    • 在父组件中添加(或者说是修改)这样的代码:
    <AppendList appendList={ this.state.list }/>
    
    • 将我们的list数据传递给AppendList,然后在AppendList中,我们需要接收数据。
    this.props.appendList
    
    • 但是我们的数据需要渲染成一个列表,所以用map来渲染。
    import React from "react"
    export default class AppendList extends React.Component{
    
        render() {
            return(
                    <ul>
                        {
                            this.props.appendList.map((data,index) => <li key={ index }>{ data }</li>)
                        }
                    </ul>
            )
        }
    }
    
    

    处理完了显示的组件,我们来接着处理添加的功能。
    基于状态在哪个组件,更新状态的行为就在那个组件的原则,我们需要先在appendFather中定义一个方法来添加数据:

    addList(todo){
            const {list} = this.state;
            list.unshift(todo);
            // 更新状态
            this.setState({list});
        }
    

    这里的todo参数是我们一会儿要在append组件中传入的数据
    注意我们需要在constructor中对这个方法的this进行绑定以免出错。

        constructor(props){
            super(props);
    
            this.state={
                list:["苹果","梨子","香蕉"]
            }
            this.addList=this.addList.bind(this);
        }
    

    现在,我们的父组件已经定义好了一个添加数据的方法,下面我们需要交给子组件来操作。
    既然普通数据可以通过props传递,那么我们的函数也可以通过props传递,而且函数传递的值只是一个对内存的引用。
    现在我们在父组件传递这个函数:

        render() {
            return(
                <div>
                    <h1>Simple TODO List</h1>
                    <Append addList={this.addList}/>
                    <AppendList appendList={ this.state.list }/>
                </div>
            )
        }
    

    现在,我们可以在append中接收这个函数了,但是首先我同样需要给append中的添加按钮加上一个处理事件:

    import React from "react"
    export default class Append extends React.Component{
        constructor(props){
            super(props);
    
            this.handleAdd = this.handleAdd.bind(this);    
        }
    
        handleAdd(){
            const todo= this.todoInput.value.trim();
            this.props.addList(todo);
            this.todoInput.value="";
        }
        render() {
            return(
                <div>
                    <input type="text" ref={input => this.todoInput=input}/>
                    <button value="添加" onClick={this.handleAdd}>添加</button>
                </div>
            )
        }
    }
    
    

    在上面的代码中,主要有以下几点:

    • 添加一个handleAdd的处理事件
    • 在处理事件中,通过ref={input => this.todoInput=input}input的值进行绑定
    • 通过this.handleAdd = this.handleAdd.bind(this);绑定自定义事件的this
    • 通过this.props.addList(todo);调用父组件传来的函数

    以上就是整个小功能的全部过程

    消息的订阅、发布(组件通信)

    相当于绑定监听、触发事件。

    使用PubSubJs库

    npm install pubsub-js
    

    总结

    以上代码,子传父最关键的就是父组件通过props传了一个函数给子组件,并在子组件中调用这个函数。

    全部代码

    appendFather.js

    import React from "react"
    import AppendList from "./appendList"
    import Append from "./append"
    export default class AppendFather extends React.Component{
        constructor(props){
            super(props);
    
            this.state={
                list:["苹果","梨子","香蕉"]
            }
            this.addList=this.addList.bind(this);
        }
    
        addList(todo){
            const {list} = this.state;
            list.unshift(todo);
            // 更新状态
            this.setState({list});
        }
        render() {
            return(
                <div>
                    <h1>Simple TODO List</h1>
                    <Append addList={this.addList}/>
                    <AppendList appendList={ this.state.list }/>
                </div>
            )
        }
    }
    

    append.js

    import React from "react"
    export default class Append extends React.Component{
        constructor(props){
            super(props);
    
            this.handleAdd = this.handleAdd.bind(this);    
        }
    
        handleAdd(){
            const todo= this.todoInput.value.trim();
            this.props.addList(todo);
            this.todoInput.value="";
        }
        render() {
            return(
                <div>
                    <input type="text" ref={input => this.todoInput=input}/>
                    <button value="添加" onClick={this.handleAdd}>添加</button>
                </div>
            )
        }
    }
    
    

    appendList.js

    import React from "react"
    export default class AppendList extends React.Component{
    
        render() {
            return(
                    <ul>
                        {
                            this.props.appendList.map((data,index) => <li key={ index }>{ data }</li>)
                        }
                    </ul>
            )
        }
    }
    
    

    相关文章

      网友评论

          本文标题:React组件之间的通信

          本文链接:https://www.haomeiwen.com/subject/mllgpftx.html