实战 React 之组件通信(父组件向子组件,子组件向父组件)

实战 React 之组件通信(父组件向子组件,子组件向父组件)

前言

React 与 Vue 最大的相通之处就是两者都是单页面应用,页面与页面之间,功能与功能之间,都是一个个的组件构成。组件也有层级结构,父与子关系,子与父关系,兄弟关系等。那么有关系的组件之间如何通信?将是本文探讨的主题。

一、父组件与子组件通信

父组件向子组件传值直接通过属性的方式,子组件通过 props 接收。
父组件调用子组件方法是通过给子组件绑定 ref 获取子组件实例。随后找到子组件的方法并调用。

父组件 TodoList.js

import React from 'react';
import TodoItem from './TodoItem';
export default class TodoList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            taskList: []
        };
        this.taskList = [];
    }
    //添加任务列表
    add() {
        var value = this.refs.input.value;
        this.taskList.push({text: value});
        this.setState({
            taskList: this.taskList
        })
    }
    del() {
        //通过ref找到子组件实例,调用del方法。
        this.refs.item.del('完成');
    }
    render() {
        return <div>
            <input type="text" ref="input"/>
            <button onClick={() => this.add()}>添加待办</button>
            <TodoItem
                taskList={this.state.taskList}
                ref="item"
            />
            <button onClick={() => this.del()}>删除包含完成的事项</button>
        </div>
    }
}

子组件 TodoItem.js

import React from 'react';
export default class TodoItem extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            taskList:[]
        }
    }
    componentWillReceiveProps(state){
        //获取父组件最新的taskList,更新子组件的taskList
        this.setState({
            taskList:state.taskList
        })
    }
    //提供del方法给父组件使用
    del(str){
        var taskList = this.state.taskList.filter((item)=>item.text.indexOf(str)<0);
        this.setState({
            taskList:taskList
        })
    }
    render() {
        return <div>
            {this.state.taskList.map((item,index)=>{
             return<div key={index}>
                 {item.text}
            </div>
            })}
        </div>
    }
}

二、子组件与父组件通信

子组件调用父组件的方法也是通过 props 属性。

父组件 TodoList.vue

import React from 'react';
import TodoItem from './TodoItem';
export default class TodoList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            taskList: [{text:"完成国际会议",done:true},{text:"未完成国内会议",done:false}],
            tip:'未删除'
        };
    }
    //父组件的方法供子组件调用
    del(str) {
        var taskList = this.state.taskList.filter((item)=>!item.done);
        this.setState({
            taskList:taskList,
            tip:str
        })
    }
    render() {
        return <div>
            <TodoItem
                taskList={this.state.taskList}
                ref="item"
                onFilter={(str)=>this.del(str)}
            />
            <div>结果:{this.state.tip}</div>
        </div>
    }
}

子组件 TodoItem.vue

import React from 'react';
export default class TodoItem extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            taskList:props.taskList
        }
    }
    componentWillReceiveProps(state){
        console.log(state);
        //获取父组件最新的taskList,更新子组件的taskList
        this.setState({
            taskList:state.taskList
        })
    }
    //提供del方法给父组件使用
    del(){
        const {onFilter} = this.props;
        if(onFilter){
            onFilter('删除完成')
        }
    }
    render() {
        return <div>
            {this.state.taskList.map((item,index)=>{
             return<div key={index}>
                 {item.text}
            </div>
            })}
            <button onClick={() => this.del()}>删除包含完成的事项</button>
        </div>
    }
}

三、其他组件通信

其他组件通信可使用 Redux 状态管理工具。其核心思想是将所有状态集中管理,一处有变动。其他地方同步更新。可参考 Redux 官方文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值