Github搜索案例
1.布局
-
App.js
-
Search
-
List
-
把html 先放在 App.js中
-
把 class 改成 className
-
style 样式设置
style={{width:'100px'}}
-
-
样式放到 App.css中
-
在public 中设一个文件css 引入 bootstrap.css
-
在 index.html 中 导入bootstrap
<link rel="stylesheet" href="./css/bootstrap.css">
-
组件拆分 components
- List
- Search
-
在App.js中导入 List Search组件
2.List的设置
- 1.a标签 加一个 rel=“noreferrer”
- 2.img 标签 加一格alt 属性 alt=“head_portrait” (头像)
3.Search的设置
-
1.给搜索按钮 绑定一个 点击 事件
<button onClick={this.search}>搜索</button>
-
2.获取input的数据(ref 回调形式)
//把 keyWorldElement 挂载到 this 上 ref={c=>{this.keyWorldElement = c}}
-
3.实现 这个搜索的 回调函数(search)
search = ()=>{ //获取用户信息 //连续解构赋值 + 重命名 为 keyWorld const {keyWorldElement:{value:keyWorld}}= this //发送网路请求 }
-
4.请求地址: https://api.github.com/search/users?q=atguigu
-
5.发送网络请求 安装 axios (npm i axios)
-
导入 axios
import axios from 'axios'
-
回调函数 search
search = ()=>{ //获取用户信息 //连续解构赋值 + 重命名 为 keyWorld const {keyWorldElement:{value:keyWorld}}= this //发送网路请求 axios.get(`https://api.github.com/search/users?q=${keyWorld}`).then( response =>{console.log('成功了',response.data)}, error =>{console.log('失败了',error)} ) }
-
-
6.解决跨域
-
1.后端 cors
-
2.启动 5000 服务器 server
npm start
-
3.如果 请求github 成功了 就users 失败了就 走 users2
search = ()=>{ //获取用户信息 //连续解构赋值 + 重命名 为 keyWorld const {keyWorldElement:{value:keyWorld}}= this //发送网路请求 axios.get(`http://localhost:3000/search/users?q=${keyWorld}`).then( response =>{console.log('成功了',response.data)}, error =>{console.log('失败了',error)} ) }
-
4.解决跨域(src 中新建一个 setupProxy.js)
//common.js 写法 const proxy = require('http-proxy-middleware') module.exports = function (app){ app.use( proxy('/api1',{//遇见/api1 前缀的请求 就会触发代理 target:'http://localhost:5000',//把请求发送给谁 changeOrigin:true,//控制服务器收到的请求头中Host字段 的值 pathRewrite:{'^/api1':''} //重新请求路基 }), ) }
-
5.一定要 在3000端口号后 加 api1前缀
search = ()=>{ //获取用户信息 //连续解构赋值 + 重命名 为 keyWorld const {keyWorldElement:{value:keyWorld}}= this //发送网路请求 axios.get(`http://localhost:3000/api1/search/users?q=${keyWorld}`).then( response =>{console.log('成功了',response.data)}, error =>{console.log('失败了',error)} ) }
-
4.Search 搜索回来的东西 交给 List 使用
-
兄弟不能直接通信 通过 App解决 (子传父)
-
1.搜索回来的交给App所以要在App中初始化状态
state = { users:[],//users 初始值为数组 isFirst:true,//是否为第一次打开页面 isLoading:false,//是否处于加载中 err:'',//存储请求相关的错误信息 }
-
2.定义方法更新App 的 state
// 更新App 的state updateAppState =(stateObj)=>{ this.setState(stateObj) }
-
3.把updateAppState 的方法交给 Search
<Search updateAppState ={this.updateAppState}/>
-
4.Search 中 发送请求之前 更新状态
//发送请求前通知APP 更新状态 this.props.updateAppState({isFirst:false,isLoading:true})
-
5.Search 中 请求成功后 通知App更新状态
response =>{ //请求成功后通知APP更新状态 this.props.updateAppState({isLoading:false,users:response.data.items}) },
-
6.Search 中 请求失败 后通知App 更新状态
error => { //请求失败后通知App更新状态,不要直接存错误对象error this.props.updateAppState({isLoading:false,err:error.message}) }
5.List
-
1.把Search中传递回来的 state 传递给 List 渲染页面
<List {...this.state}/>
-
2.List 中 把 users isFirst isLoading err 从 this.props中取出来
const { users, isFirst, isLoading, err } = this.props;
-
3.三元运算判断 并渲染页面
return ( <div className="row"> { isFirst ? <h2>欢迎使用,输入关键字,搜索</h2>: isLoading ? <h2>isLoading......</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="head_portrait" src={userObj.avatar_url} style={{ width: "100px" }} /> </a> <p className="card-text">userObj.login</p> </div> ); })} </div>
-
4.把 userObj.login (人的名字) userObj.avatar_url(头像) userObj.html_url(点击路径)填到对应地方
-
5.return 的 那个 div 里 要加一个 key={userObj.id}