react-github案例

 2023-09-10 阅读 19 评论 0

摘要:github案例 一 react脚手架配置代理_方法一 需要理解的概念有: axios模块的安装与使用什么是跨域跨域的解决方案有哪些proxy的限制有什么 webpack github、https://cra.docschina.org/docs/proxying-api-requests-in-development 测试代理服务器项目:http://qn.

github案例

一 react脚手架配置代理_方法一

需要理解的概念有:

  • axios模块的安装与使用
  • 什么是跨域
  • 跨域的解决方案有哪些
  • proxy的限制有什么

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"

说明:

  1. 优点:配置简单,前端请求资源时可以不加任何前缀。
  2. 缺点:不能配置多个代理。
  3. 工作方式:上述方式配置代理,当用Ajax请求了3000不存在的资源时,那么该请求会转发给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"
}

二 react脚手架配置代理_方法二

需要理解的概念有:

  • 代理中间件的使用
  1. 第一步:创建代理配置文件

    在src下创建配置文件:src/setupProxy.js
    
  2. 编写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': '' },}));
    };
    

说明:

  1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
  2. 缺点:配置繁琐,前端请求资源时必须加前缀。

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;

三 github搜索案例_静态页面

需要理解的概念有:

  • 组件的拆分
  • 静态资源的引入位置
  • className与style的应用
  • a标签rel='noreferrer’的配合
  • img标签alt属性的设置

静态页面:http://qn.chinavanes.com/users_page.zip

image-20210518190945235

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' />&nbsp;<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>

四 github搜索案例_axios发送请求

需要理解的概念有:

  • input对象的获取,ref的三种操作方式:字符串、回调、createRef
  • axios的请求
  • github服务器端开放了cors,所以没有跨域问题

1.回调函数的ref设置应用

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='请输入搜索的用户名称' />&nbsp;<button onClick={this.search}>搜索</button></div></section>);}
}

2.createRef的ref设置应用

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='请输入搜索的用户名称' />&nbsp;<button onClick={this.search}>搜索</button></div></section>);}
}

五 github搜索案例_展示数据

需要理解的概念有:

  • 属性的传递,数组与函数
  • map与forEach的差异
  • 循环时key的设置

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='请输入搜索的用户名称' />&nbsp;<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>);}
}

六 github搜索案例_完成案例

需要理解的概念有:

  • 请求的不同状态,加载中,加载完成,加载错误
  • 展开式批量参数传递
  • 解构赋值
  • 三元运算的应用

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='请输入搜索的用户名称' />&nbsp;<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>);}
}

七 消息订阅与发布技_pubsub

需要理解的概念有:

  • 订阅及发布模式
  • 事件的发布与订阅
  • 生命周期钩子函数
  • 组件的嵌套与层次结构

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='请输入搜索的用户名称' />&nbsp;<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>);}
}

八 fetch发送请求

需要理解的概念有:

  • ajax、axios、fetch之间的差异与区别

1.jQuery ajax

$.ajax({type: 'POST',url: url,data: data,dataType: dataType,success: function () {},error: function () {}
});

优势与不足点:

  • 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
  • 基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
  • JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)

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);
});

优势与不足点:

  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 客户端支持防止CSRF
  • 提供了一些并发请求的接口(重要,方便了很多的操作)

3.fetch

try {let response = await fetch(url);let data = response.json();console.log(data);
} catch(e) {console.log("Oops, error", 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.适用于任意组件间通信
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中进行取消订阅

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/40125.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息