React兄弟组件之间的通讯

2023-11-04

案例要求:
在这里插入图片描述
达到这样一个效果

组件拆分:

  • 搜索框是一个组件,传递状态
  • 下面的展示列表是一个组件,使用状态

方式一:状态存在父组件之间

父组件传递给子组件消息可以使用props,子组件给父组件之间传递消息可以使用函数实现
APP组件代码

import React, { Component } from 'react'
import Search from './components/Search/Search'
import './App.css'
import List from './components/List/List'

export default class App extends Component {
    state={ //初始化状态,状态初始化时要初始化对
        items:[], //初始为数组
        isFirst:true,
        isLoading:false,
        err:''
    }
    getData=(items) => {
        this.setState({items:items})
    }
    setFirst=() => {
        this.setState({isFirst:false})
    }
    setLoading=() => {
        const {isLoading}=this.state
        // this.state.setState({isLoading:!this.state.isLoading})
        console.log(isLoading)
        this.setState({isLoading:!isLoading})
    }
    setErr=(errInfo) => {
        this.setState({err:errInfo})
    }
    render() {
        const {items,isFirst,isLoading,err}=this.state
        return (
            <div className="container">
                {/*这个地方传的时候可以一下子传一个对象,后面更改的时候只需传需要更改的字段就行,因为是覆盖的,不传就不会更改 */}
                <Search getData={this.getData} setFirst={this.setFirst} setLoading={this.setLoading} setErr={this.setErr}/> 
                <List items={items} isFirst={isFirst} isLoading={isLoading} err={err}/>
            </div>
        )
    }
}

search组件代码

import React, { Component } from 'react'
import axios from 'axios'
export default class Search extends Component {

    search=() => {
        //1、获取用户输入
        const {input:{value:keyword}}=this
        this.props.setFirst()
        this.props.setLoading() 
        this.props.setErr("")//每次请求之前把err清空
        //2、发送网络请求
        axios.get(`http://localhost:3000/api1/search/users?q=${keyword}`).then( //如果站的位置就是发送请求的位置,可以把http://localhost:3000省略
        //这里面只能写response和error
            response=>{
          //这里面不函数后面不能写,不然会被当做表达式,在这里面不能setLoading,为什么这里的函数调不了
                this.props.setLoading()
                this.props.getData(response.data.items)
                console.log('ccc')
            },
            error => {
                // console.log('失败了',error),
                this.props.setLoading()
                this.props.setErr(error)
            }
        )
    }
    render() {
        return (
            <section className="jumbotron">
                <h3 className="jumbotron-heading">搜索github用户</h3>
                <div>
                    <input ref={(currentNode) => {this.input=currentNode}} type="text" placeholder="输入关键词"/>&nbsp;
                    <button onClick={this.search}>搜索</button>
                </div>
            </section>
        )
    }
}

list组件代码

import React, { Component } from 'react'
import './List.css'
export default class List extends Component {
    render() {
        const {items}=this.props
        if (this.props.isFirst) {
            return <div><h2>欢迎来到该界面</h2></div>
        }
        if(this.props.isLoading){
            return <div><h2>Loading.....</h2></div>
        }
        if(this.props.err!==""){
            return <div><span>{this.props.err}</span></div>
        }
        return (
            <div className="row">
                {
                    items.map((item) => {
                        return (
                            <div className="card" key={item.id}>
                                <a href={item.html_url}>
                                    <img alt="head_picture" src={item.avatar_url} style={{width: '100px'}}></img>
                                </a>
                                <p className="card-text">{item.login}</p>
                            </div>                           
                        )
                    })
                }
             </div>
        )
    }
}

方式二:消息订阅,该方式为常用方式,方便简单

状态在操作组件中定义,消息在传递状态的组件中发布,在使用状态的组件中订阅。使用PubSubJS库实现消息订阅。
搜索框组件代码

import React, { Component } from 'react'
import axios from 'axios'
import PubSub from 'pubsub-js'
export default class Search extends Component {

  
        // //1、获取用户输入
        // const {input:{value:keyword}}=this
        // this.props.setFirst()
        // this.props.setLoading() 
        // this.props.setErr("")//每次请求之前把err清空
        // //2、发送网络请求
        // axios.get(`http://localhost:3000/api1/search/users?q=${keyword}`).then( //如果站的位置就是发送请求的位置,可以把http://localhost:3000省略
        // //这里面只能写response和error
        //     response=>{
        //   //这里面不函数后面不能写,不然会被当做表达式,在这里面不能setLoading,为什么这里的函数调不了
        //         this.props.setLoading()
        //         this.props.getData(response.data.items)
        //         console.log('ccc')
        //     },
        //     error => {
        //         // console.log('失败了',error),
        //         this.props.setLoading()
        //         this.props.setErr(error)
        //     }
        // )
        search=() => { 
            const {input:{value:keyword}}=this
            PubSub.publish('state',{isFirst:false,err:'',isLoading:true}) //发布消息
            axios.get(`http://localhost:3000/api1/search/users?q=${keyword}`).then(
                response => {
                    PubSub.publish('state',{isLoading:false,items:response.data.items})
                },
                error =>{
                    PubSub.publish('state',{isLoading:false,err:error})
                }
            )
    }
    render() {
        return (
            <section className="jumbotron">
                <h3 className="jumbotron-heading">搜索github用户</h3>
                <div>
                    <input ref={(currentNode) => {this.input=currentNode}} type="text" placeholder="输入关键词"/>&nbsp;
                    <button onClick={this.search}>搜索</button>
                </div>
            </section>
        )
    }
}

展示列表组件代码:

import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import './List.css'
export default class List extends Component {
    state={ //初始化状态,状态初始化时要初始化对
        items:[], //初始为数组
        isFirst:true,
        isLoading:false,
        err:''
    }
    componentDidMount(){
        //组件挂载到页面后,该函数开启定时器或者订阅消息
        PubSub.subscribe('state',(_,data) => {
            //这里返回的token是供componentWillUnmount()关闭定时器或者取消订阅时候使用的
            this.token=this.setState(data) //data是一个状态对象,订阅消息后,当组件卸载的时候,还要取消订阅

        })
    }
    componentWillUnmount(){
        //组件即将卸载的时候,该函数关闭定时器,或者取消订阅
        PubSub.unsubscribe(this.token)
    }
    render() {
        const {isFirst,isLoading,err,items}=this.state
        {/**
        if (this.props.isFirst) {
            return <div><h2>欢迎来到该界面</h2></div>
        }
        if(this.props.isLoading){
            return <div><h2>Loading.....</h2></div>
        }
        if(this.props.err!==""){
            return <div><span>{this.props.err}</span></div>
        }
         return (
            <div className="row">
                {
                    items.map((item) => {
                        return (
                            <div className="card" key={item.id}>
                                <a href={item.html_url}>
                                    <img alt="head_picture" src={item.avatar_url} style={{width: '100px'}}></img>
                                </a>
                                <p className="card-text">{item.login}</p>
                            </div>                           
                        )
                    })
                }
             </div>
        )
         */}
        return (
            <div className="row">
            {
                //连着写的三元表达式,不能用if语句,因为jsx里面只能写js表达式,不能写js语句
                isFirst?<h2>欢迎使用,输入关键字,随后点击搜索</h2>:
                isLoading?<h2>Loading.....</h2>:
                err?<h2 style={{color:'red'}}>{err}</h2>:
                items.map((item) => {
                    return (
                        <div className="card" key={item.id}>
                            <a href={item.html_url}>
                                <img alt="head_picture" src={item.avatar_url} style={{width: '100px'}}></img>
                            </a>
                            <p className="card-text">{item.login}</p>
                        </div>                           
                    )
                })
            }
        </div>    
        )
        
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React兄弟组件之间的通讯 的相关文章

  • unity 模型销毁_Unity3D常用 API 之实例化与销毁

    1 实例化游戏物体 1 1 游戏中的案例介绍 在很多 MMORPG 类的游戏中都有类似于 金钱副本 的副本关卡 在这类副 本中通常都是限定一个时间 在这个时间内玩家可以尽情的破坏 然后收集金钱 分析游戏截图讲解场景元素 见图 场景中所有的坛

随机推荐

  • latex 如何添加圆圈数字?

    众所周知 LATEX 提供了 textcircled 命令用以给字符加圈 但效果却不怎么好 实际上 加圈并不是一个平凡的变换 它会涉及到圈内字符形状的微调 而这是几乎无法在 TEX 宏层面解决的 因此 要得到比较好的效果 最好能使用预先设计
  • iwebsec靶场 文件包含漏洞通关笔记9-file://伪协议利用

    目录 前言 1 file协议 2 利用条件 1 file 用于访问本地文件系统 2 file 必须是绝对路径 第09关 file 伪协议利用 1 打开靶场 2 源码分析 3 获取 etc passwd渗透 前言 1 file协议 file协
  • QCQI学习笔记(1)

    Chapter I II overview of the quantum information probabilistic model qubit tensor product dirac notation Chapter III Sup
  • electron-上传文件,下载csv txt xlsx

    electron 主进程 渲染进程 在vue中调用接口 相互通信 csv txt 上传csv文件 将csv文件读取内容 iconv lite 解决读取内容乱码 xlsx 上传xlsx文件 xlsx文件内容读取 下载xslx文件 简单无样式的
  • 虚析构函数

    自动调用基类部分的析构函数对基类的设计有重要影响 删除指向动态分配对象的指针时 需要运行析构函数 在释放对象的内存之前清除对象 处理继承层次中的对象时 指针的静态类型可能与被删除对象的动态类型不同 可能会删除 实际指向派生类对象的基类类型指
  • Android 10 修改系统默认的字体大小

    代码路径 frameworks base core java android content res Configuration java frameworks base packages SettingsProvider res valu
  • 美团外卖智能陪伴型导购的探索与实践

    相比于其他电商场景 外卖场景对于实时发现和反馈用户兴趣的能力有着更高的要求 近年来 美团外卖算法团队摸索出了一套适用于外卖场景的智能陪伴型导购架构和策略 这一举措已经取得了显著成效 本文将详细介绍外卖搜索技术团队搭建智能陪伴型导购时 所遇到
  • 浅析深究什么是中间件

    本文发布于2009年10月30日 1 由来 因为工作的原因 我从金蝶集团调入金蝶中间件公司工作以来 经常遇到一个问题就是中间件公司是个什么公司 中间件是什么 金蝶不是做ERP的吗 怎么也做中间件 这是我以前在金蝶集团时无法想象的问题 因为金
  • R语言笔记四

    str function str Compacktly display the internal structure of an R object A diagnostic function and an alternative to su
  • AndroidUI库集合

    https hndeveloper github io 2017 github android ui html 进度条 https github com Vension V AndroidCollectSources
  • 双指针和递归

    一 双指针 1 给你一个n 给你n个数 再给一个val 去掉所有等于val的值 思路 当i和j位置都是非val值 i j 当i位置是val j 当i是val j是非val 交换 i j 当j走到最后一个位置的时候 停了 输出0 i位置的值
  • 量化术语速查表(持续更新)

    本文介绍一些量化投资相关术语 帮助大家更好地了解该行业 作者 bigquant 阅读时间 15分钟 本文由BigQuant宽客学院推出 难度标签 以下术语没有先后顺序 并将持续更新 金融相关 股票 股份公司发行的所有权凭证 债券 承诺按一定
  • GDB+Jlink调试注意事项

    1 在汇编调用C的一步要用 Step in 不要用 Step Over 因为main对于汇编来说只是一个函数 会造成程序全速运行 不能单步调试 对于汇编代码 Step in Step Over 是一样的效果 所以在进行main函数之前最好都
  • 表白代码大全_隐藏表白系列都在这里了

    点击上方 搞siao君 右上角找到 立刻设置我为 星标 置顶 每天第一时间推送给你 每天都有不一样的精彩 喜欢就多多分享哦 一 微信隐藏表白代码大全 爱你我爱你我爱你我爱你我爱你我爱你我
  • List与ArrayList的区别

    在刷题的时候发现ArrayList初始化时 有下面两种情况 List
  • 2023五大自动化测试的 Python 框架

    自2018年被评选为编程语言以来 Python在各大排行榜上一直都是名列前茅 目前 它在Tiobe指数中排名第三个 仅次于Java和C 随着该编程语言的广泛使用 基于Python的自动化测试框架也应运而生 且不断发展与丰富 因此 开发与测试
  • Nacos和Zookeeper对比

    主要平时用的较多是配置中心和服务注册中心 所以也是结合这两点功能做出对应的对比 主要比对集群模式 以下仅仅整理了个人理解后的观点 如有疑问欢迎咨询讨论 1 Zookeeper 其实明白一点Zookeeper的功能主要是它的树形节点来实现的
  • GIT Please, commit your changes or stash them before you can merge. Aborting

    用git pull来更新代码的时候 遇到了下面的问题 C error Your local changes to the following files would be overwritten by merge xxx xxx xxx p
  • Qt通过读取XML文件,绘制图形界面

    最近需要实现通过读取xml文件的形式动态绘制界面的需求 这样会很方便 在外界修改xml文件就可以了 不需要重新编译程序 一 XML文件 XML的格式和一些说明 本文就不在介绍了 菜鸟教程有更清晰的入门介绍 菜鸟教程 XML 二 QT中读取X
  • React兄弟组件之间的通讯

    案例要求 达到这样一个效果 组件拆分 搜索框是一个组件 传递状态 下面的展示列表是一个组件 使用状态 方式一 状态存在父组件之间 父组件传递给子组件消息可以使用props 子组件给父组件之间传递消息可以使用函数实现 APP组件代码 impo