React基于脚手架的基本使用

459 阅读5分钟

这一篇主要写了React脚手架使用,axios,代理配置,消息订阅和发布,以及fetch

React脚手架

React脚手架是一个工具,能够帮我们快速的生成项目的工程化结构!

脚手架安装

全局安装: npm i -g create-react-app
切换到想创项目的目录,使用命令: create-react-app 文件名

项目结构

hello-react
├─ .git                     // 自动创建本地仓库
├─ package.json             // 相关配置文件
├─ public                   // 公共资源
│  ├─ favicon.ico           // 浏览器顶部的icon图标
│  ├─ index.html            // 应用的 index.html入口
│  ├─ logo192.png           // logo
│  ├─ manifest.json         // 应用加壳的配置文件
│  └─ robots.txt            // 爬虫给协议文件
├─ src                      // 源码文件夹
│  ├─ App.css               // App组件的样式
│  ├─ App.js                // App组件
│  ├─ App.test.js           // 用于给APP做测试
│  ├─ index.css             // 样式
│  ├─ index.js              // 入口文件
│  ├─ logo.svg              // logo图
│  ├─ reportWebVitals.js    // 页面性能分析文件
│  └─ setupTests.js         // 组件单元测试文件
└─ package-lock.json

publuc下index.html代码解读

<!DOCTYPE html>
<html lang="en">
  <head>
  <meta charset="utf-8" />
  <!-- %PUBLIC_URL%代表public文件夹的路径 -->
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
  <!-- 开启理想视口,用于做移动端网页的适配 -->
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <!-- 用于配置浏览器页签+地址栏的颜色(仅支持安卓手机浏览器) -->
    <meta name="theme-color" content="red" />
    <meta
      name="description"
      content="Web site created using create-react-app"
  />
  <!-- 用于指定网页添加到手机主屏幕后的图标 -->
  <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
  <!-- 应用加壳时的配置文件 -->
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
  <!-- 若不支持js则展示标签中的内容 -->
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

React使用axios发送客户端请求

React 本身只关注于页面,并不包含发送Ajax请求的代码,所以一般都是集成第三方的包,比较推荐的就是axios

axios安装

import axios from 'axios'

使用

import axios from 'axios'
axios.get('http://192.168.189.1:3000/api1/search/users').then(
  response => {
    // 成功的处理
  },
  error => {
    // 失败的处理
  }
)

脚手架中配置代理

在我们开发中经常会遇到跨域的问题,跨域源于浏览器的同源策略。所谓同源(即指在同一个域)就是两个页面具有相同的协议,主机和端口号, 当一个请求URL的协议、域名、端口三者之间任意一个与当前页面URL不同即为跨域,下面我们就用前端的方式来解决一下跨域。

全局代理

第一种方法,我把它叫做全局代理,因为它直接将代理配置在了配置文件 package.json 中

"proxy":"http://localhost:5000" // 要请求的地址
这样配置代理时,首先会在原请求地址上访问,如果访问不到文件,就会转发到这里配置的地址上去请求
优点:配置简单,前端请求资源可以不加任何前缀,缺点:不能配置多个代理

工作方式:当请求了接口首先会在本地找你所请求的资源,如果没有会通过代理像5000端口发起请求,数据返回之后再由代理发给客户端,以此来解决跨域,但是这种方式也存在一些问题:
1. 当本地又访问的文件的话,就不会在向服务器发起请求
2. 因为这种方式采用的是全局配置的关系,导致只能转发到一个地址,不能配置多个代理

单独配置(可配置多个代理)

首先 我们需要在React脚手架 src 目录下,创建代理配置文件 setupProxy.js,然后在setupProxy.js里配置代理,这样就可以配置多个代理了
注意:*这个文件只能叫这个名字,脚手架在启动的时候,会自动执行这些文件*
优点:可以配置多个代理,可以灵活的控制请求是否走代理
缺点:配置繁琐,前端请求资源时必须加前缀
const { createProxyMiddleware } = require('http-proxy-middleware')
module.exports = function (app) {
  app.use(
    createProxyMiddleware('/api1', {// 遇见 /api 前缀的请求,就会触发该代理配置
      target: 'http://localhost:5000',// 请求转发给谁
      changeOrigin: true,//控制服务器收到的响应头中Host字段的值
      pathRewrite: {
        '^/api1': ''//重新请求路径
      }
    }),
     createProxyMiddleware('/api2', {// 遇见 /api 前缀的请求,就会触发该代理配置
      target: 'http://localhost:5001',// 请求转发给谁
      changeOrigin: true,//控制服务器收到的响应头中Host字段的值
      pathRewrite: {
        '^/api2': ''//重新请求路径
      }
    }),
  )
}

消息订阅发布

之前由于还没有学到兄弟组件传值,所写的案例都是通过子组件传递给父组件,父组件再传递给子组件,略嫌麻烦,下面学习了消息订阅发布,我们就可以实现兄弟组件之间直接通信!

pubsub-js安装

npm install pubsub-js --save

使用

// 引入
import PubSub from 'pubsub-js'

订阅消息

我们通过subscribe来订阅消息,它接收两个参数,第一个参数是消息的名称,第二个是消息成功的回调,回调中也接受两个参数,一个是message,一个是接收到的数据(谁接收消息谁就订阅消息)

// 写在componentDidMount钩子中,页面已挂载完成就订阅
componentDidMount(){
  this.token = PubSub.subscribe('search',(msg,data)=>{
    console.log(msg,data);
  })
}

发布消息

我们采用 publish 来发布消息,用法如下

// 比如再点搜索后进行消息发布
clickSearch = ()=>{
  PubSub.publish('search',{name:'tom',age:18})
}

取消订阅

// 页面卸载时取消订阅
// 在页面要卸载时,在 componentWillUnmount() 钩子里,通过 unsubscribe 来取消指定的订阅
componentWillUnmount(){
  PubSub.unsubscribe(this.token)
}

扩展 -- Fetch

fetch也是一种发送请求的方式,它是在xhr之外的一种,我们平常用的Jquery和axios都是封装xhr的第三方库,而fetch是官方自带的,同时它也采用的是Promise的方式,更好的关注分离(比如请求接口,成功了并不是先返回数据,而是告诉你接口是好的可以访问,想要拿到接口返回的数据还需要进行进一步的操作)

fetch('http://xxx')
  .then(response => response.json())
  .then(json => console.log(json))
  .catch(err => console.log('Request Failed', err)); 
和axios不同的是,fetch关注分离,它在第一次请求时,不会直接返回数据,会先返回联系服务器的状态,在第二步中才能够获取到数据我们需要在第一次then中返回response.json()因为这个是包含数据的 promise对象,再调用一次then方法即可得到数据,我们可以利用 async 和 await 配合使用,来简化代码
async function getJSON() {
  let url = 'https://xxx';
  try {
    let response = await fetch(url);
    return await reasponse.json();
  } catch (error) {
    console.log('Request Failed', error);
  }
}

小结

下一篇就开始学习React中的路由了!Go、Go、Go!