• 【React组件】github搜索案例之 父子组件通信 (附源码)


    上篇文章学习了如何通过代理方式实现跨域,这篇文章通过一个案例来运用上篇文章的代理的知识,并且教大家如何通过父子组件传值,从而实现兄弟组件之间通信。

    📦github搜索案例

    1️⃣需求

    上方的输入框输入关键词,点击搜索按钮,下方展示关键词对应的github用户

    点击头像可以跳转到该用户github的主页

    2️⃣效果

    在这里插入图片描述

    3️⃣分析父子组件如何通信

    使用create-react-app脚手架搭建的项目,拆分组件:最外层App父组件,里面分别为Search和List子组件。

    Search组件用来根据用户输入的信息发送网络请求,获取用户数据,要想使获取到的数据及时渲染到页面(即List组件),就要将Search组件获取到的数据传递给List组件,即兄弟组件之间传值,但是由于兄弟组件之间没法进行通信(下篇文章中会讲到兄弟组件之间如何通信),就需要先将Search子组件的数据通过props传给App父组件,然后App父组件将数据通过props传给List子组件,利用父子组件通信,实现了兄弟组件之间的通信。

    在这里插入图片描述

    4️⃣目录结构

    在这里插入图片描述

    5️⃣代码

    index.js:

    // 引入react核心库
    import React from 'react'
    // 引入ReactDOM
    import ReactDOM from 'react-dom/client'
    // 引入App
    import App from './App'
    
    // 创建虚拟DOM
    const root = ReactDOM.createRoot(document.getElementById('root'))
    // 渲染虚拟DOM到页面
    root.render(
      <React.StrictMode>
      {/* 检查App组件以及子组件里的一些代码是否有不合理的地方 */}
      <App />
      </React.StrictMode>
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    父组件App.jsx:

    import React, { Component } from 'react';
    import Search from './components/Search'
    import List from './components/List';
    
    export default class App extends Component {
      state = { //初始化状态
        users: [], //users初始值为数组
        isFirst: true, //是否为第一次打开页面
        isLoading: false, //标识是否处于加载中
        err: '' //存储请求相关的错误信息
      }
    
      // search组件获取到的数据先传给父组件App,父组件再传给List组件
      // 更新App的state
      updateAppState = (stateObj) => {
        this.setState(stateObj)
      }
    
      render() {
        return (
          <div className="container">
          <Search updateAppState={this.updateAppState} />
    <List {...this.state} />
    </div>
    );
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    子组件Search_index.jsx:

    import React, { Component } from 'react'
    import axios from 'axios'
    
    export default class Search extends Component {
      search = () => {
        // 获取用户的输入(解构赋值的连续写法+重命名)
        const { keyWordElement: { value: keyWord } } = this
        // 发送请求前通知App更新状态
        this.props.updateAppState({ isFirst: false, isLoading: true })
        // 发送网络请求  
        // 站在3000端口给3000发请求,可以省略http://localhost:3000
        axios.get(`/api1/search/users?q=${keyWord}`).then(
          response => {
            // 请求成功后通知App更新状态
            this.props.updateAppState({ isLoading: false, users: response.data.items })
          },
          error => {
            // 请求失败后通知App更新状态
            this.props.updateAppState({ isLoading: false, err: error.message })
          }
        )
      }
    
      render() {
        return (
          <section className="jumbotron">
          <h3 className="jumbotron-heading">搜索github用户</h3>
          <div>
          <input ref={c => this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索" />&nbsp;
      <button onClick={this.search}>搜索</button>
    </div>
    </section>
    )
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    子组件List_index.jsx:

    import React, { Component } from 'react'
    import './index.css'
    
    export default class List extends Component {
      render() {
        const { users, isFirst, isLoading, err } = this.props
        return (
          <div className="row">
            {
              isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</h2> :
                isLoading ? <h2>Loading.....</h2> :
                  err ? <h2 style={{ color: 'red' }}>{err}</h2> :
                    users.map((userObj) => {
                      return (
                        <div key={userObj.id} className="card">
                          <a rel="noreferrer" href={userObj.html_url} target="_blank">
                            <img alt="avatar" src={userObj.avatar_url} style={{ width: '100px' }} />
                          </a>
                          <p className="card-text">{userObj.login}</p>
                        </div>
                      )
                    })
            }
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    setupProxy.js:

    const { createProxyMiddleware } = require('http-proxy-middleware')
    
    module.exports = function (app) {
      app.use(
        createProxyMiddleware('/api1', {
          target: 'http://localhost:5000',
          changeOrigin: true,
          pathRewrite: { '^/api1': '' }
        })
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    List_index.css:

    .album {
      min-height: 50rem;
      /* Can be removed; just added for demo purposes */
      padding-top: 3rem;
      padding-bottom: 3rem;
      background-color: #f7f7f7;
    }
    
    .card {
      float: left;
      width: 33.333%;
      padding: .75rem;
      margin-bottom: 2rem;
      border: 1px solid #efefef;
      text-align: center;
    }
    
    .card>img {
      margin-bottom: .75rem;
      border-radius: 100px;
    }
    
    .card-text {
      font-size: 85%;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    💥总结

    在一个React项目中,组件之间的通信是非常重要的环节。

    父组件在展示子组件,可能会传递一些数据给子组件:

    1. 父组件通过 属性=值 的形式来传递给子组件数据
    2. 子组件通过 props 参数获取父组件传递过来的数据

    子组件向父组件传递消息:

    1. 父组件给子组件传递一个回调函数
    2. 在子组件中通过 props 调用这个函数即可。

    今天的分享就到这里啦 ✨
    如果对你有帮助的话,还请👉🏻关注💖点赞🤞收藏⭐评论🔥哦
    不定时回访哟🌹

  • 相关阅读:
    uni-app 小程序跳转其他小程序方法
    2022华为机试真题 C++ 实现【非严格递增连续数字序列】
    每日五问(java)
    sql:SQL优化知识点记录(十四)
    聚观早报 | 特斯拉发布赛博啤酒套装;小米汽车售价曝光
    GLTF模型添加关节控制
    数据结构与算法之美学习笔记:16 | 二分查找(下):如何快速定位IP对应的省份地址?
    Eclipse的常用快捷键
    电脑怎么把照片变成jpg格式?
    vue中动态引入图片
  • 原文地址:https://blog.csdn.net/xuxuii/article/details/125583311