还是依赖熟悉的第三方库 axios
分为 搜索组件 和展示区组件 搜索组件成功请求回来数据后 在经过最外部组件来传导
- //import axios from 'axios';
- import React, { Component } from 'react'
- import './App.css';
- import Result from './component/Result';
- import Search from './component/Search';
- export default class App extends Component {
-
- state = {
- resultData:[],
- statepos:{
- isFirst:true,
- Loading:false,
- error:''
- }
- }
-
- initResData = (data,pos) =>{
- this.setState({
- resultData:data,
- statepos:{...this.state.statepos,...pos}
- })
- }
-
- componentDidMount(){
- console.log(233)
- }
-
-
- render(){
- console.log(123)
- return (
- <div className="container">
- <Search initResData={this.initResData}>Search>
- <Result {...this.state}>Result>
- div>
- )
- }
- }
搜索组件:
触发搜索按钮时 根据输入框的字符串发起请求,请求成功后map筛选出自己要用的数据 触发props 传进来的函数 、 数据转存到 父组件 state.reslutData中 并更新当前的状态
- import axios from 'axios'
- import React, { Component } from 'react'
-
- export default class Search extends Component {
-
-
- initData = () =>{
- const keyStr = this.input1.value
- this.props.initResData(null,{isFirst:false,Loading:true})
- axios.get(`https://api.github.com/search/users?q=${keyStr}`).then(res =>{
- const arr1 = res.data.items.map(x =>{
- return {id:x.id,avatar_url:x.avatar_url,html_url:x.html_url,login:x.login}
- })
- this.props.initResData(arr1,{Loading:false})
- }).catch(err =>{
- this.props.initResData(null,{error:err.message,Loading:false})
- })
- }
-
- render() {
- return (
- <section className="jumbotron">
- <h3 className="jumbotron-heading">Search Github Usersh3>
- <div>
- <input type="text" ref={c => this.input1 = c} style={{width:'50%'}} placeholder="输入要搜索的登录名(避免汉字)"/>
- <button onClick={this.initData}>Searchbutton>
- div>
- section>
- )
- }
- }
展示结果组件:
接过去渲染数据
体验优化:三元表达式连续写法 一开始显示提示语 发送请求时 显示 Loading
刚进入页面是 isFirst : true 提示用户输入关键词进行检索
发起网络请求时 isFirst : false loading : true 提示等待动画
请求成功 等待动画关闭 显示数据界面
失败了就显示错误信息
- import React, { Component } from 'react'
-
- export default class Result extends Component {
- render() {
- const {resultData,statepos:{isFirst,Loading,error}} = this.props
- return (
- <div className="row">
- {
- // 三元表达式连续写法
- isFirst ? <h3>请输入用户名检索用户h3> :
- Loading ? <h3>Loadingh3> :
- error ? <h3 style={{color:'red'}}>{error}h3> :
- (resultData || []).map(x =>{
- return (
- <div className="card" key={x.id}>
- <a href={x.html_url} rel="noreferrer" target="_blank">
- <img src={x.avatar_url} alt='头像' style={{width:'100px'}}/>
- a>
- <p className="card-text">{x.login}p>
- div>
- )
- })
- }
- div>
- )
- }
- }
最外部的组件:把子组件引入放进去 就可以了
- import React, { Component } from 'react'
- import './App.css';
- import Result from './component/Result';
- import Search from './component/Search';
- export default class App extends Component {
- render(){
- return (
- <div className="container">
- <Search>Search>
- <Result>Result>
- div>
- )
- }
- }
搜索组件:
引入相关包
import PubSub from 'pubsub-js'
发送请求的时候发布消息
PubSub.publish('消息的名称',{传递的数据})
- import axios from 'axios'
- import PubSub from 'pubsub-js'
- import React, { Component } from 'react'
-
- export default class Search extends Component {
-
-
- initData = () =>{
- const keyStr = this.input1.value
- PubSub.publish('wsg',{isFirst:false,Loading:true})
- axios.get(`https://api.github.com/search/users?q=${keyStr}`).then(res =>{
- const arr1 = res.data.items.map(x =>{
- return {id:x.id,avatar_url:x.avatar_url,html_url:x.html_url,login:x.login}
- })
- PubSub.publish('wsg',{resultData:arr1,Loading:false})
- }).catch(err =>{
- PubSub.publish('wsg',{error:err.message,Loading:false})
- })
- }
-
- render() {
- return (
- <section className="jumbotron">
- <h3 className="jumbotron-heading">Search Github Usersh3>
- <div>
- <input type="text" ref={c => this.input1 = c} style={{width:'50%'}} placeholder="输入要搜索的登录名(避免汉字)"/>
- <button onClick={this.initData}>Searchbutton>
- div>
- section>
- )
- }
- }
结果页的组件:
组件挂载到页面上时就 实时的订阅 消息 根据接收的消息 this.setState 自己的状态
componentDidMount(){
this.token = PubSub.subscribe('wsg',(a,stateObj)=>{
console.log(a) // 还是显示名字 wsg 所以一般用 _ 占位就行 也不使用
this.setState(stateObj) // 只会已更新有的
})
}卸载时 就取消订阅消息
componentWillUnmount(){
PubSub.unsubscribe(this.token)
}
- import React, { Component } from 'react'
- import PubSub from 'pubsub-js'
- export default class Result extends Component {
- state = {
- resultData:[],
- isFirst:true,
- Loading:false,
- error:''
- }
-
- componentDidMount(){
- this.token = PubSub.subscribe('wsg',(a,stateObj)=>{
- console.log(a) // 还是显示名字 wsg 所以一般用 _ 占位就行 也不使用
- this.setState(stateObj) // 只会已更新有的
- })
- }
-
- componentWillUnmount(){
- PubSub.unsubscribe(this.token)
- }
- render() {
- const {resultData,isFirst,Loading,error} = this.state
- return (
- <div className="row">
- {
- // 三元表达式连续写法
- isFirst ? <h3>请输入用户名检索用户h3> :
- Loading ? <h3>Loadingh3> :
- error ? <h3 style={{color:'red'}}>{error}h3> :
- (resultData || []).map(x =>{
- return (
- <div className="card" key={x.id}>
- <a href={x.html_url} rel="noreferrer" target="_blank">
- <img src={x.avatar_url} alt='头像' style={{width:'100px'}}/>
- a>
- <p className="card-text">{x.login}p>
- div>
- )
- })
- }
- div>
- )
- }
- }