React ajax

目录标题

  • react ajax
    • 使用axios
      • get
      • post
    • github搜索实践
      • 代理设置(setupProxy.js)
      • 整体规划
    • 订阅发布
      • github案例重做
    • Fetch
      • github搜索案例

源码地址:https://github.com/BLKNjyty/reactstudy

react ajax

  1. React本身只关注于界面, 并不包含发送ajax请求的代码

  2. 前端应用需要通过ajax请求与后台进行交互(json数据)

  3. react应用中需要集成第三方ajax库(或自己封装)

使用axios

  1. jQuery: 比较重, 如果需要另外引入不建议使用

  2. axios: 轻量级, 建议使用

  1. 封装XmlHttpRequest对象的ajax

  2. promise风格

  3. 可以用在浏览器端和node服务器端

get

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });

axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

post

axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

github搜索实践

伪造服务器,资料:05-所需服务器。作为我们发送给github的代理。

案例样例:搜索用户名,返回githubd的样例

数据传递:父子=》props,兄弟=》使用props,消息由子传递给父再传递给子

代理设置(setupProxy.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':''} //重写请求路径(必须)
		})
	)
}

整体规划

export default class App extends Component{
	state={
		users:[],
		isFirst:true,
		isLoading:false,
		err:'',
	}
	updateAppState=(stateObj)=>{
		this.setState(stateObj)
	}
	render(){
		return (
			<div className="container">
				<Search updateAppState={this.updateAppState}/>
                <List {...this.state}/>
			</div>
		)
	}
}
export default class Search extends Componet{

	search=()=>{
		const {keyWordElement:{value:keyword}}=this
		this.props.updateAppState({isFirst:fasle,isLoading:true})
		axios.get(`/api1/search/users`q=${keyWord}).then(
			response=>{
				this.props.updateAppState({isLoading:false,users:response.data.items})
			},
			error=>{
				this.props.updateAppState({isLoading:false,err:error.message})
			}
		)
	}
	render(){
		return (
			<section>
				<h3 className="jumbotron-heading">搜索github用户</h3>
				<div>
					<input ref={c=>this.keyWordElement=c} type="text" placeholder="输入关键字" >&nbsp;
					<button onClick={this.search}>搜索</button>
				</div>
			</section>
		)
	}
	
}
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="head_portrait" src={userObj.avatar_url} style={{width:'100px'}}/>
								</a>
								<p className="card-text">{userObj.login}</p>
							</div>
                        )
                    })
            	}
            </div>
        )
    }
}

订阅发布

任意组件之间的消息通信。

之前消息通讯只能是:父子组件通过props属性

  1. 工具库: PubSubJS

  2. 下载: npm install pubsub-js --save

  3. 使用:

    1) import PubSub from 'pubsub-js' //引入
    
    2) PubSub.subscribe('delete', function(data){ }); //订阅
    
    3) PubSub.publish('delete', data) //发布消息
    

github案例重做

由于由订阅发布功能,那么list组件的数据状态自己保存即可,不需要交给app了

export default class App extends Component {
	render() {
		return (
			<div className="container">
				<Search/>
				<List/>
			</div>
		)
	}
}
export default class List extends Component {
    state = { //初始化状态
		users:[], //users初始值为数组
		isFirst:true, //是否为第一次打开页面
		isLoading:false,//标识是否处于加载中
		err:'',//存储请求相关的错误信息
	} 
	//只要有人发布主题atguigu,执行后边的函数:第一个参数是订阅主题,第二个参数是收到的消息
	componentDidMount(){
		this.token = PubSub.subscribe('atguigu',(_,stateObj)=>{
			this.setState(stateObj)
		})
	}

	componentWillUnmount(){
		PubSub.unsubscribe(this.token)
	}
	render(){
        const{users,isFirst,isLoading,err}=this.state
        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="head_portrait" src={userObj.avatar_url} style={{width:'100px'}}/>
								</a>
								<p className="card-text">{userObj.login}</p>
							</div>
						)
					})
				}
            </div>
        )
    }
}
export default class Search extends Component {
    search=()=>{
        const {keyWordElement:{value:keyword}}=this
        PubSub.publish('heiheihei',{isFirst:false,isLoading:true})
        axios.get(`/api1/search/users?q=${keyWord}`).then(
        	response=>{
                //请求成功后通知List更新状态
				PubSub.publish('atguigu',{isLoading:false,users:response.data.items})
            },
            error=>{
                //请求失败后通知App更新状态
				PubSub.publish('atguigu',{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>
		)
	}
}

Fetch

  1. fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求
  2. 老版本浏览器可能不支持
  3. 是Promise风格的

github搜索案例

search = async()=>{
		//发送网络请求---使用fetch发送(优化)
		try {
			const response= await fetch(`/api1/search/users2?q=${keyWord}`)
			const data = await response.json()
			console.log(data);
			PubSub.publish('atguigu',{isLoading:false,users:data.items})
		} catch (error) {
			console.log('请求出错',error);
			PubSub.publish('atguigu',{isLoading:false,err:error.message})
		}
	}

本文内容参考b站尚硅谷 链接

你可能感兴趣的:(前端,react.js,ajax,javascript)