文章目录
上篇文章学习了如何通过代理方式实现跨域,这篇文章通过一个案例来运用上篇文章的代理的知识,并且教大家如何通过父子组件传值,从而实现兄弟组件之间通信。
📦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'// 引入ReactDOMimport ReactDOM from'react-dom/client'// 引入Appimport App from'./App'// 创建虚拟DOMconst root = ReactDOM.createRoot(document.getElementById('root'))// 渲染虚拟DOM到页面
root.render(<React.StrictMode>{/* 检查App组件以及子组件里的一些代码是否有不合理的地方 */}<App /></React.StrictMode>)
父组件App.jsx:
import React,{ Component }from'react';import Search from'./components/Search'import List from'./components/List';exportdefaultclassAppextendsComponent{
state ={//初始化状态users:[],//users初始值为数组isFirst:true,//是否为第一次打开页面isLoading:false,//标识是否处于加载中err:''//存储请求相关的错误信息}// search组件获取到的数据先传给父组件App,父组件再传给List组件// 更新App的stateupdateAppState=(stateObj)=>{this.setState(stateObj)}render(){return(<div className="container"><Search updateAppState={this.updateAppState}/><List {...this.state}/></div>);}}
子组件Search_index.jsx:
import React,{ Component }from'react'import axios from'axios'exportdefaultclassSearchextendsComponent{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="输入关键词点击搜索"/> <button onClick={this.search}>搜索</button></div></section>)}}
子组件List_index.jsx:
import React,{ Component }from'react'import'./index.css'exportdefaultclassListextendsComponent{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>)}}
setupProxy.js:
const{ createProxyMiddleware }=require('http-proxy-middleware')
module.exports=function(app){
app.use(createProxyMiddleware('/api1',{target:'http://localhost:5000',changeOrigin:true,pathRewrite:{'^/api1':''}}))}
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%;}
💥总结
在一个React项目中,组件之间的通信是非常重要的环节。
父组件在展示子组件,可能会传递一些数据给子组件:
- 父组件通过
属性=值
的形式来传递给子组件数据 - 子组件通过
props
参数获取父组件传递过来的数据
子组件向父组件传递消息:
- 父组件给子组件
传递一个回调函数
- 在子组件中通过
props
调用这个函数即可。
今天的分享就到这里啦 ✨
如果对你有帮助的话,还请👉🏻关注💖点赞🤞收藏⭐评论🔥哦
不定时回访哟🌹
版权归原作者 努力成为一名合格的程序员 所有, 如有侵权,请联系我们删除。