create-react-app从一个新项目到一个请求
最近在学习react,想着画些小页面练练手,于是就想着拿些酷狗的api调用玩玩。
首先命令行create-react-app appName建立一个名为appName的react项目。然后npm start运行项目,浏览器输入localhost:3000可以看到页面就ok了。
按照官方demo说的,Edit src/App.js and save to reload。在src/App.js下随便修改了文字,查看页面变化,似乎木有任何变化,浏览器刷新才看到变化。没有热更新,忍不了,找到webpack文档,在入口文件index.js中添加一段代码
//模块热替换的API if(module.hot){ module.hot.accept(); }
修改下代码ctrl+s保存,看下页面,瞬间很舒服。然后安装axios,安装react-router-dom,前者用来请求,后者用来设置页面路由。
npm install axios;
npm install react-router-dom;
然后在src下新建plugins/axios/index.js,这步不配置也行,目前怎么简单怎么来
import axios from 'axios'; axios.defaults.headers['Content-Type'] = 'application/json'; let config = { timeout: 60 * 1000, // Timeout withCredentials: true, }; const _axios = axios.create(config); _axios.interceptors.request.use( (config) => { // Do something before request is sent config.headers['Authorization'] = ''; return config; }, (error) => { // Do something with request error return Promise.reject(error); } ); // Add a response interceptor _axios.interceptors.response.use( (response) => { // Do something with response data return response }, (error) => { // Do something with response error return Promise.reject(); } ); export default _axios;
然后在入口文件index.js引入
import axios from "./plugins/axios";
然后修改下App.js,我这里UI库用的阿里的ant-design,之前vue用的都是ElemengUI,这次换个UI库试玩玩。
import './App.css'; import {HashRouter, Route, Switch} from 'react-router-dom'; import React, {Component} from 'react'; import 'antd/dist/antd.css'; import { Layout, Menu, Breadcrumb } from 'antd'; import myMusic from './views/myMusic'; import discoverMusic from './views/discoverMusic' const { Header, Content, Footer } = Layout; class App extends Component { render() { return ( <Layout className="layout"> <Header> <div className="logo">聚合音乐</div> <Menu theme="dark" mode="horizontal"> <Menu.Item key="1"><a href='#/discoverMusic'>发现音乐</a></Menu.Item> <Menu.Item key="2"><a href='#/myMusic'>我的音乐</a></Menu.Item> <Menu.Item key="3"><a href='#/firstView'>样式选择</a></Menu.Item> </Menu> </Header> <Content style={{ padding: '0 50px' }}> <Breadcrumb style={{ margin: '16px 0' }}> <Breadcrumb.Item>Home</Breadcrumb.Item> <Breadcrumb.Item>List</Breadcrumb.Item> <Breadcrumb.Item>Music</Breadcrumb.Item> </Breadcrumb> <div className="site-layout-content"> <HashRouter> <Switch> <Route exact path="/myMusic" component={myMusic}/> <Route exact path="/discoverMusic" component={discoverMusic}/> </Switch> </HashRouter> </div> </Content> <Footer style={{ textAlign: 'center' }}>Uni-Music App ©2020 Created by JDWu</Footer> </Layout> ); } } export default App;
大致页面显示如下:
discoverMusic中的代码为:
import { Input } from 'antd'; import { MehOutlined } from '@ant-design/icons'; import React from 'react'; import axios from 'axios' const { Search } = Input; class discoverMusic extends React.Component{ constructor() { super(); this.state = { inpValue: "" }; } render() { return( <div> <Search placeholder="请输入音乐名称" style={InputWidth} enterButton="查询" size="large" prefix={<MehOutlined />} onSearch={onSearch}/> </div> ) } } const onSearch = value => { var params={ format:'json', keyword:value, page:1, pagesize:20, showtype:1 } axios.get('v3/search/song',{params:params}).then(data=>{ console.log(data) }) } const InputWidth={ width:'30%', } export default discoverMusic
注意这里的axios请求,如果写成axios.get('http://mobilecdn.kugou.com/api/v3/search/song')直接调用别人家的api就会出现一个老生常谈的跨域问题。
解决跨域的最简单的方法就是在package.json中添加proxy字段,这个只能在开发中使用,打包之后就没啥用了,跨域就得靠nginx配置来实现了,我上述的代码就是这样实现解决跨域问题的。
网上还有一种比较复杂的:通过koa2-cors中间件进行代理转发。这里也记录一下,毕竟也试了一水,毕竟谁都有个搞全栈的梦,前后端通吃是吧。
安装koa2,koa-router(请求路由,与react-router是两个东西哦),koa-compose(洋葱模型依赖于这个),koa2-cors(解决跨域的中间件)。
npm install koa
npm install koa-router
npm install koa-compose
npm install koa2-cors
然后在项目根目录下新建server/server.js,routes.js,index.js三个文件
server.js代码:
const Koa= require('koa') const app = new Koa() const routes = require('./routes.js'); const cors = require('koa2-cors'); //运行跨域 app.use(cors()); //路由 app.use(routes()); app.listen(3001,()=>{ console.log('port is running at 3001') })
routes.js代码:
const compose = require('koa-compose'); const Router = require('koa-router'); var router = new Router(); const Index = require('./index'); router.get('/api/index', Index.index) // app.use(router.routes()).use(router.allowedMethods()); module.exports = (ctx, next) => compose([router.routes(), router.allowedMethods()]);
index.js代码:
const axios = require('axios') class Index { static async index(ctx,next){ const {format,keyword,page,pagesize,showtype} =ctx.request.query; const {data} = await axios.get('http://mobilecdn.kugou.com/api',{params:{ format:format, keyword:keyword, page:page, pagesize:pagesize, showtype:showtype }}) console.log(data) ctx.body=data } } module.exports = Index
则页面的请求需要修改为:axios.get('http://localhost:3001/api/index')。然后命令行
cd server 进入server文件夹
node server.js 启动koa服务端
看到port is running at 3001就代表koa后端服务启动好了,然后就又可以愉快的发请求了。