需要理解的概念有:
webpack github、https://cra.docschina.org/docs/proxying-api-requests-in-development
测试代理服务器项目:http://qn.chinavanes.com/test_proxy_server.zip
react项目?在package.json中追加如下配置
"proxy":"http://localhost:5000"
说明:
react ui库、src/App.js
import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {render() {// 解构赋值return <div className='todo-container'></div>;}componentDidMount() {this.getData();}getData = () => {axios.get('/students').then((res) => {console.log(res);});};
}
export default App;
package.json
proxy不能是数组,只能是单一代理地址,不能代理多个。
{"name": "hello-react","version": "0.1.0","private": true,"dependencies": {"@testing-library/jest-dom": "^5.11.4","@testing-library/react": "^11.1.0","@testing-library/user-event": "^12.1.10","axios": "^0.21.1","nanoid": "^3.1.23","react": "^17.0.2","react-dom": "^17.0.2","react-scripts": "4.0.3","web-vitals": "^1.0.1"},"scripts": {"start": "react-scripts start","build": "react-scripts build","test": "react-scripts test","eject": "react-scripts eject"},"eslintConfig": {"extends": ["react-app","react-app/jest"]},"browserslist": {"production": [">0.2%","not dead","not op_mini all"],"development": ["last 1 chrome version","last 1 firefox version","last 1 safari version"]},"devDependencies": {"@babel/plugin-transform-runtime": "^7.14.2","@babel/preset-flow": "^7.13.13"},"proxy": "http://localhost:5000"
}
需要理解的概念有:
第一步:创建代理配置文件
在src下创建配置文件:src/setupProxy.js
编写setupProxy.js配置具体代理规则:
const proxy = require('http-proxy-middleware')
// 默认已经安装,不需要再安装module.exports = function (app) {app.use('/demo', //请求前缀,代理服务器只有遇到端口号后面带有/api的请求才会转发给服务器proxy({target: 'http://localhost:5000', //配置真正服务器的地址changeOrigin: true, //该配置写不写无所谓pathRewrite: { '^/demo': '' },}));app.use('/test', //请求前缀,代理服务器只有遇到端口号后面带有/api的请求才会转发给服务器proxy({target: 'http://localhost:5001', //配置真正服务器的地址changeOrigin: true, //该配置写不写无所谓pathRewrite: { '^/test': '' },}));
};
说明:
src/App.js
import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {render() {// 解构赋值return <div className='todo-container'></div>;}componentDidMount() {this.getData();}getData = () => {axios.get('/demo/students').then((res) => {console.log(res);});};
}
export default App;
需要理解的概念有:
静态页面:http://qn.chinavanes.com/users_page.zip
src/App.js
import React, { Component } from 'react';
import Search from './components/Search';
import List from './components/List';class App extends Component {render() {return (<div className='container'><Search /><List /></div>);}
}
export default App;
src/components/Search/index.js
import React, { Component } from 'react';export default class Search extends Component {render() {return (<section className='jumbotron'><h3 className='jumbotron-heading'>Search Github Users</h3><div><input type='text' placeholder='enter the name you search' /> <button>Search</button></div></section>);}
}
src/components/List/index.js
import React, { Component } from 'react';
import './index.css';export default class List extends Component {render() {return (<div className='row'><div className='card'><a rel='noreferrer' href='https://github.com/reactjs' target='_blank'><imgsrc='https://avatars.githubusercontent.com/u/6412038?v=3'style={{ width: '100px' }}alt='avatar'/></a><p className='card-text'>reactjs</p></div></div>);}
}
src/components/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%;
}
public/index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><link rel="icon" href="%PUBLIC_URL%/favicon.ico" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>React App</title><link rel="stylesheet" href="./css/bootstrap.css">
</head><body><div id="root"></div>
</body></html>
需要理解的概念有:
src/components/Search/index.js
import React, { Component } from 'react';
import axios from 'axios';export default class Search extends Component {search = () => {const {keywordElement: { value: keyword },} = this; // 解构+赋值别名// 关键字可以尝试用`atguigu`axios.get(`https://api.github.com/search/users?q=${keyword}`).then((res) => {console.log(res);},(err) => {console.log(err);});};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>);}
}
src/components/Search/index.js
import React, { Component } from 'react';
import axios from 'axios';export default class Search extends Component {keyword = React.createRef();search = () => {const {current: { value: keyword },} = this.keyword; // 解构+赋值别名// 关键字可以尝试用`atguigu`axios.get(`https://api.github.com/search/users?q=${keyword}`).then((res) => {console.log(res);},(err) => {console.log(err);});};render() {return (<section className='jumbotron'><h3 className='jumbotron-heading'>搜索github用户</h3><div><input ref={this.keyword} type='text' placeholder='请输入搜索的用户名称' /> <button onClick={this.search}>搜索</button></div></section>);}
}
需要理解的概念有:
src/App.js
import React, { Component } from 'react';
import Search from './components/Search';
import List from './components/List';class App extends Component {state = { users: [] };saveUsers = (users) => {this.setState({ users });};render() {const { users } = this.state;return (<div className='container'><Search saveUsers={this.saveUsers} /><List users={users} /></div>);}
}
export default App;
src/components/Search/index.js
import React, { Component } from 'react';
import axios from 'axios';export default class Search extends Component {keyword = React.createRef();search = () => {const {current: { value: keyword },} = this.keyword; // 解构+赋值别名// 关键字可以尝试用`atguigu`axios.get(`https://api.github.com/search/users?q=${keyword}`).then((res) => {console.log(res);this.props.saveUsers(res.data.items);},(err) => {console.log(err);});};render() {return (<section className='jumbotron'><h3 className='jumbotron-heading'>搜索github用户</h3><div><input ref={this.keyword} type='text' placeholder='请输入搜索的用户名称' /> <button onClick={this.search}>搜索</button></div></section>);}
}
src/components/List/index.js
import React, { Component } from 'react';
import './index.css';export default class List extends Component {render() {const { users } = this.props;return (<div className='row'>{users.map((userObj) => (<div className='card' key={userObj.id}><a rel='noreferrer' href={userObj.html_url} target='_blank'><img src={userObj.avatar_url} style={{ width: '100px' }}alt='avatar' /></a><p className='card-text'>{userObj.login}</p></div>))}</div>);}
}
需要理解的概念有:
src/App.js
import React, { Component } from 'react';
import Search from './components/Search';
import List from './components/List';class App extends Component {state = {users: [],isFirst: true, // 是否第一次打开isLoading: false, // 是否显示isLoadingerr: '', // 错误提示内容};updateAppState = (stateObj) => {this.setState(stateObj);};render() {return (<div className='container'><Search updateAppState={this.updateAppState} /><List {...this.state} /></div>);}
}
export default App;
src/components/Search/index.js
import React, { Component } from 'react';
import axios from 'axios';export default class Search extends Component {keyword = React.createRef();search = () => {const {current: { value: keyword },} = this.keyword; // 解构+赋值别名// 发送请求前通知App更新状态this.props.updateAppState({ isFirst: false, isLoading: true });// 关键字可以尝试用`atguigu`axios.get(`https://api.github.com/search/users?q=${keyword}`).then((res) => {// 请求成功以后通知App更新状态this.props.updateAppState({ isLoading: false, users: res.data.items });},(err) => {// 请求失败以后通知App更新状态this.props.updateAppState({ isLoading: false, err: err });});};render() {return (<section className='jumbotron'><h3 className='jumbotron-heading'>搜索github用户</h3><div><input ref={this.keyword} type='text' placeholder='请输入搜索的用户名称' /> <button onClick={this.search}>搜索</button></div></section>);}
}
src/components/List/index.js
import React, { Component } from 'react';
import './index.css';export default class List extends Component {render() {const { isFirst, isLoading, err, users } = this.props;return (<div className='row'>{isFirst ? (<h2>欢迎使用,输入关键字,随后点击搜索</h2>) : isLoading ? (<h2>Loading...</h2>) : err ? (<h2 style={{ color: 'red' }}>{err.toString()}</h2>) : (users.map((userObj) => (<div className='card' key={userObj.id}><a rel='noreferrer' href={userObj.html_url} target='_blank'><img src={userObj.avatar_url} style={{ width: '100px' }} alt='avatar' /></a><p className='card-text'>{userObj.login}</p></div>)))}</div>);}
}
需要理解的概念有:
src/App.js
import React, { Component } from 'react';
import Search from './components/Search';
import List from './components/List';class App extends Component {render() {return (<div className='container'><Search /><List /></div>);}
}
export default App;
src/components/Search/index.js
import React, { Component } from 'react';
import axios from 'axios';
import PubSub from 'pubsub-js';export default class Search extends Component {keyword = React.createRef();search = () => {const {current: { value: keyword },} = this.keyword; // 解构+赋值别名// 发送请求前通知List更新状态PubSub.publish('pubsubEvent', { isFirst: false, isLoading: true });// 关键字可以尝试用`atguigu`axios.get(`https://api.github.com/search/users?q=${keyword}`).then((res) => {// 请求成功以后通知List更新状态PubSub.publish('pubsubEvent', { isLoading: false, users: res.data.items });},(err) => {// 请求失败以后通知List更新状态PubSub.publish('pubsubEvent', { isLoading: false, err: err });});};render() {return (<section className='jumbotron'><h3 className='jumbotron-heading'>搜索github用户</h3><div><input ref={this.keyword} type='text' placeholder='请输入搜索的用户名称' /> <button onClick={this.search}>搜索</button></div></section>);}
}
src/components/List/index.js
import React, { Component } from 'react';
import './index.css';import PubSub from 'pubsub-js';export default class List extends Component {state = {users: [],isFirst: true, // 是否第一次打开isLoading: false, // 是否显示isLoadingerr: '', // 错误提示内容};componentDidMount() {this.psEvent = PubSub.subscribe('pubsubEvent', (_, data) => {this.setState(data);});}componentWillUnmount() {PubSub.unsubscribe(this.psEvent);}render() {// this.props转成this.stateconst { isFirst, isLoading, err, users } = this.state;return (<div className='row'>{isFirst ? (<h2>欢迎使用,输入关键字,随后点击搜索</h2>) : isLoading ? (<h2>Loading...</h2>) : err ? (<h2 style={{ color: 'red' }}>{err.toString()}</h2>) : (users.map((userObj) => (<div className='card' key={userObj.id}><a rel='noreferrer' href={userObj.html_url} target='_blank'><img src={userObj.avatar_url} style={{ width: '100px' }} alt='avatar' /></a><p className='card-text'>{userObj.login}</p></div>)))}</div>);}
}
需要理解的概念有:
1.jQuery ajax
$.ajax({type: 'POST',url: url,data: data,dataType: dataType,success: function () {},error: function () {}
});
优势与不足点:
2.axios
axios({method: 'post',url: '/user/12345',data: {firstName: 'Fred',lastName: 'Flintstone'}
})
.then(function (response) {console.log(response);
})
.catch(function (error) {console.log(error);
});
优势与不足点:
3.fetch
try {let response = await fetch(url);let data = response.json();console.log(data);
} catch(e) {console.log("Oops, error", e);
}
优势与不足点:
为什么要用axios?
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:
需要理解的概念有:
1.拆分静态组件,设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办
2.分析得知:Search组件负责搜索,List组件负责展示,状态要交给App
3.List组件不仅要展示用户信息,还要展示:欢迎词、loading、错误信息
4.在App中设计一个方法:getSearchInfo去更新App的状态,一个一个写太麻烦
5.批量的给List组件传递参数:<List {...this.state}/>
6.在List中用三目运算符进行连续判断,从而决定List组件展示什么
7.先订阅,再发布(理解:有一种隔空对话的感觉)
8.适用于任意组件间通信
rror", e);
}
优势与不足点:- 符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
- 更好更方便的写法
- 更加底层,提供的API丰富(request, response)
- 脱离了XHR,是ES规范里新的实现方式1)fetchtch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理2)fetch默认不会带cookie,需要添加配置项3)fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费4)fetch没有办法原生监测请求的进度,而XHR可以**为什么要用axios?**axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:- 从浏览器中创建 XMLHttpRequest
- 从 node.js 发出 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据客户端支持防止CSRF/XSRF# 九 总结github搜索案例需要理解的概念有:1.拆分静态组件,设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办
2.分析得知:Search组件负责搜索,List组件负责展示,状态要交给App
3.List组件不仅要展示用户信息,还要展示:欢迎词、loading、错误信息
4.在App中设计一个方法:getSearchInfo去更新App的状态,一个一个写太麻烦
5.批量的给List组件传递参数:`<List {...this.state}/>`
6.在List中用三目运算符进行连续判断,从而决定List组件展示什么
7.先订阅,再发布(理解:有一种隔空对话的感觉)
8.适用于任意组件间通信
9.componentDidMount中订阅消息,要在组件的componentWillUnmount中进行取消订阅
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态