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={
    '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后端服务启动好了,然后就又可以愉快的发请求了。

原文地址:https://www.cnblogs.com/jdWu-d/p/14024323.html