一、React 配置代理
1、在package.json文件中配置代理
(1)具体实现
- package.json
"proxy":"http://localhost:5000"- App.jsx
importReact,{Component}from"react";importaxiosfrom"axios";exportdefaultclassAppextendsComponent{getStudentData=()=>{axios.get("/students").then((response)=>{console.log("成功了",response.data);},(error)=>{console.log("失败了",error);},);};render(){return(<div><button onClick={this.getStudentData}>点我获取学生数据</button></div>);}}(2)小结
- 工作方式:当请求了 3000 不存在的资源时,那么该请求会转发给5000(优先匹配前端资源)
优点:配置简单,前端请求资源时可以不加任何前缀
缺点:不能配置多个代理
2、在setupProxy.js文件中配置代理
(1)具体实现
- 在 src 目录下创建并配置 setupProxy.js 文件
const{createProxyMiddleware}=require("http-proxy-middleware");module.exports=function(app){app.use(createProxyMiddleware("/api1",{target:"http://localhost:5000",changeOrigin:true,pathRewrite:{"^/api1":""},}),createProxyMiddleware("/api2",{target:"http://localhost:5001",changeOrigin:true,pathRewrite:{"^/api2":""},}),);};- App.jsx
importReact,{Component}from"react";importaxiosfrom"axios";exportdefaultclassAppextendsComponent{getStudentData=()=>{axios.get("http://localhost:3000/api1/students").then((response)=>{console.log("成功了",response.data);},(error)=>{console.log("失败了",error);},);};getCarData=()=>{axios.get("http://localhost:3000/api2/cars").then((response)=>{console.log("成功了",response.data);},(error)=>{console.log("失败了",error);},);};render(){return(<div><button onClick={this.getStudentData}>点我获取学生数据</button><button onClick={this.getCarData}>点我获取汽车数据</button></div>);}}(2)解读
/api1是需要转发的请求,target 是转发目标地址,所有带有/api1前缀的请求都会转发给 target
createProxyMiddleware("/api1",{target:"http://localhost:5000",...})- 控制服务器接收到的请求头中 Host 字段的值,changeOrigin 默认值为 false,但我们一般设置为 true
1. changeOrigin 设置为 true 时,服务器收到的请求头中的 Host 字段为:localhost:5000 2. changeOrigin 设置为 false 时,服务器收到的请求头中的 Host 字段为:localhost:3000changeOrigin:true,- 去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
pathRewrite:{"^/api2":""},(3)小结
优点:可以配置多个代理,可以灵活的控制请求是否走代理
缺点:配置繁琐,前端请求资源时必须加前缀
二、搜索案例(Fetch + PubSub)
- List 组件
importReact,{Component}from"react";importPubSubfrom"pubsub-js";import"./index.css";exportdefaultclassListextendsComponent{state={users:[],isFirst:true,isLoading:false,err:"",};componentDidMount(){this.token=PubSub.subscribe("test",(msgName,stateObj)=>{this.setState(stateObj);});}componentWillUnmount(){PubSub.unsubscribe(this.token);}render(){const{users,isFirst,isLoading,err}=this.state;return(<div className="row">{isFirst?(<h3>欢迎使用,输入关键字,随后点击搜索</h3>):isLoading?(<h3>Loading...</h3>):err?(<h3 style={{color:"red"}}>{err}</h3>):(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>);}}.album{min-height:50rem;padding-top:3rem;padding-bottom:3rem;background-color:#f7f7f7;}.card{float:left;width:33.333%;padding:0.75rem;margin-bottom:2rem;border:1px solid #efefef;text-align:center;}.card > img{margin-bottom:0.75rem;border-radius:100px;}.card-text{font-size:85%;}- Search 组件
importReact,{Component}from"react";importPubSubfrom"pubsub-js";exportdefaultclassSearchextendsComponent{search=async()=>{// 获取用户的输入(连续解构赋值 + 重命名)const{keyWordElement:{value:keyWord},}=this;// 发送请求前通知更新状态PubSub.publish("test",{isFirst:false,isLoading:true});try{constresponse=awaitfetch(`/api1/search/users?q=${keyWord}`);constdata=awaitresponse.json();// 请求成功后通知更新状态PubSub.publish("test",{isLoading:false,users:data.items});}catch(error){// 请求失败后通知更新状态PubSub.publish("test",{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="输入关键词点击搜索"/> <button onClick={this.search}>搜索</button></div></section>);}}- App 组件
importReact,{Component}from"react";importSearchfrom"./components/Search";importListfrom"./components/List";exportdefaultclassAppextendsComponent{render(){return(<div className="container"><Search/><List/></div>);}}- index.js
importReactfrom"react";// 引入 React 核心库importReactDOMfrom"react-dom";// 引入 ReactDOMimportAppfrom"./App";// 引入 App 组件// 渲染 App 组件到页面ReactDOM.render(<App/>,document.getElementById("root"));- setupProxy.js
const{createProxyMiddleware}=require("http-proxy-middleware");module.exports=function(app){app.use(createProxyMiddleware("/api1",{target:"http://localhost:5000",changeOrigin:true,pathRewrite:{"^/api1":""},}),);};三、React 路由基本使用
- About 组件
importReact,{Component}from"react";exportdefaultclassAboutextendsComponent{render(){return<h3>About Content</h3>;}}- Home 组件
importReact,{Component}from"react";exportdefaultclassHomeextendsComponent{render(){return<h3>Home Content</h3>;}}- App 组件
importReact,{Component}from"react";import{Link,Route}from"react-router-dom";importHomefrom"./components/Home";importAboutfrom"./components/About";exportdefaultclassAppextendsComponent{render(){return(<div><h2>React Router Demo</h2><div><Link to="/about">About</Link><Link to="/home">Home</Link></div><div><Route path="/about"component={About}/><Route path="/home"component={Home}/></div></div>);}}- index.js
importReactfrom"react";// 引入 React 核心库importReactDOMfrom"react-dom";// 引入 ReactDOMimportAppfrom"./App";// 引入 App 组件import{BrowserRouter}from"react-router-dom";// 渲染 App 组件到页面ReactDOM.render(<BrowserRouter><App/></BrowserRouter>,document.getElementById("root"),);四、NavLink
1、基本介绍
Link:单纯的页面跳转组件,提供导航功能
NavLink:是 Link 的特殊版本,除了导航功能,它会自动给当前激活的链接添加样式或类名
- NavLink 的 activeClassName 用于自定义激活类名,默认是 active
2、基本使用
- About 组件
importReact,{Component}from"react";exportdefaultclassAboutextendsComponent{render(){return<h3>About Content</h3>;}}- Home 组件
importReact,{Component}from"react";exportdefaultclassHomeextendsComponent{render(){return<h3>Home Content</h3>;}}- App 组件
importReact,{Component}from"react";import{NavLink,Route}from"react-router-dom";importHomefrom"./components/Home";importAboutfrom"./components/About";import"./App.css";exportdefaultclassAppextendsComponent{render(){return(<div><h2>React Router Demo</h2><div><NavLink activeClassName="selected"className="list-group-item"to="/about">About</NavLink><NavLink activeClassName="selected"className="list-group-item"to="/home">Home</NavLink></div><div><Route path="/about"component={About}/><Route path="/home"component={Home}/></div></div>);}}.active{color:red;font-weight:bold;background-color:#f0f0f0;}.selected{color:blue;font-weight:bold;background-color:#f0f0f0;}- index.js
importReactfrom"react";// 引入 React 核心库importReactDOMfrom"react-dom";// 引入 ReactDOMimportAppfrom"./App";// 引入 App 组件import{BrowserRouter}from"react-router-dom";// 渲染 App 组件到页面ReactDOM.render(<BrowserRouter><App/></BrowserRouter>,document.getElementById("root"),);3、NavLink 封装
(1)pages
- About 组件
importReact,{Component}from"react";exportdefaultclassAboutextendsComponent{render(){return<h3>About Content</h3>;}}- Home 组件
importReact,{Component}from"react";exportdefaultclassHomeextendsComponent{render(){return<h3>Home Content</h3>;}}(2)components
- MyNavLink 组件
importReact,{Component}from"react";import{NavLink}from"react-router-dom";import"./index.css";exportdefaultclassMyNavLinkextendsComponent{render(){return<NavLink activeClassName="selected"className="list-group-item"{...this.props}/>;}}.active{color:red;font-weight:bold;background-color:#f0f0f0;}.selected{color:blue;font-weight:bold;background-color:#f0f0f0;}(3)main
- App 组件
importReact,{Component}from"react";import{Route}from"react-router-dom";importHomefrom"./pages/Home";importAboutfrom"./pages/About";importMyNavLinkfrom"./components/MyNavLink/index";exportdefaultclassAppextendsComponent{render(){return(<div><h2>React Router Demo</h2><div><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div><div><Route path="/about"component={About}/><Route path="/home"component={Home}/></div></div>);}}- index.js
importReactfrom"react";// 引入 React 核心库importReactDOMfrom"react-dom";// 引入 ReactDOMimportAppfrom"./App";// 引入 App 组件import{BrowserRouter}from"react-router-dom";// 渲染 App 组件到页面ReactDOM.render(<BrowserRouter><App/></BrowserRouter>,document.getElementById("root"),);