react项目开发过程中常见问题汇总(不定期更新)

一、打包项目后本地访问不到
package.json 里添加 “homepage”: “./”,

二、路由的基本使用
参考链接地址:链接: https://www.cnblogs.com/haiyang-/p/12096802.html.
建议使用 HashRouter组件,不建议使用BrowserRouter(如果是服务器地址的话可以使用)

自己的代码供参考 ,创建router.js和routerMap.js两个文件

/*routerMap.js  所有的页面路由配置*/
import index from '../pages/index/index' 
import login from '../pages/login /index'
import news from '../pages/news/index'
export default [
    {
      path: "/", name: "index", component: index ,chinese:'首页'},
    {
      path: "/login", name: "login", component: login ,chinese:'登录页'},
    {
      path: "/news", name: "news", component: news,chinese:'新闻动态',
	 children:[{
     
	           path: "/news/1", name: "/news/1", component: news ,chinese:'国外新闻动态',
	       },{
     
	           path: "/news/2", name: "/news/2", component: news ,chinese:'国内新闻动态',
	       },
       ]
 },
];
//router.js
import React from 'react'
import RouterMap from './routerMap'
import {
     HashRouter,Route,Switch,BrowserRouter,Link} from 'react-router-dom'

class RouterIndex extends React.Component{
     
    constructor(props){
     
        super(props);
    }
    componentDidMount() {
     

    }

    render(){
     
        return (
            // 根容器
            <HashRouter>
                    {
     /* 路由规则,Route是配置路由的规则,同时也是一个占位符 */}
                    // 首页 Link点击跳转,
                    //或者使用window.location.hash="#/"实现跳转
                    {
     RouterMap.map((item,index)=>{
     
                         if(item.children){
     ///判断是否有二级菜单
                             item.children.map((item1,index1)=>{
     
                             return <Link to={
     item1.path}>{
     item1.chinese}</Link>
                         })
                         }else{
     
                            <Link to={
     item.path}>{
     item.chinese}</Link>
                      }
                       
                    })}
                    <Switch>
                        {
     RouterMap.map((item,index)=>{
     
                           if(item.path==='/'){
     
                               return <Route key={
     index} path={
     item.path} exact component={
     item.component} />
                           }else {
     
                               return <Route key={
     index} path={
     item.path} component={
     item.component} />
                           }
                        })}
                    </Switch>
             
            </HashRouter>
        );
    }
}

在将上面的文件导入到App.js里,一个基本的路由就基本上完成了

import Router from'./route/router';//引入路由管理js
import 'antd/dist/antd.css';
function App() {
     
  return (
    <div className="App">
      <Router />
    </div>
  );
}

export default App;

如果想实现不同的功能模块公用一个页面,公用的页面导出的时候修改为
export default (props)=>;
使用key实现重新加载,重新请求接口

三、访问地址代理问题

如果遇到请求地址访问跨域问题,使用插件 http-proxy-middleware

安装方法npm install --save-dev http-proxy-middleware
或者yarn add --save-dev http-proxy-middleware
安装完成后,在项目的src下创建一个文件 setupProxy.js

const {
      createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
     
    /*app.use(
        createProxyMiddleware('/web', {
            target: 'http://192.168.1.246:8321/web',
            changeOrigin: true,
            pathRewrite: {
                "^/web": ""
            },
        }));*/
    app.use(
        createProxyMiddleware('/api', {
     
            target: 'https://xxxx.com.cn/api',
            changeOrigin: true,
            pathRewrite: {
     
                "^/api": ""
            },
        }));
};

可以有多个代理,多写几个app.use()方法就行了。接口请求的时候只需要写/api/xxx/xxx,代理就能够自动替换。

***

友情提醒,第一次插件配置好后请重新启动项目,将此插件生效。不重启无代理效果


四、axios请求配置

  1. 安装axios
npm install axios --save

或者

yarn add axios --save
  1. axios的二次封装
    创建axios.js文件
/**
 * 网络请求配置
 */
import React from 'react';
import axios from 'axios'; // 引入axios
import ReactDOM from 'react-dom';
import {
     message,Spin} from 'antd'
import './spin.css'
/**
 * http request 拦截器
 */
axios.interceptors.request.use(
    (config) => {
     
        showLoading ();//加载动画
        let gToken=localStorage.getItem('token');
      /*  config.data = JSON.stringify(config.data);*/
        config.headers = {
     //请求前添加验证信息
            "Content-Type": "application/json",
            'Authorization': gToken?'JWT '+ gToken.split("&&")[0]:''//用户身份验证信息
        };
        return config;
    },
    (error) => {
     
        return Promise.reject(error);
    }
);
/**
 * http response 拦截器
 */
axios.interceptors.response.use(
    (response) => {
     
        hideLoading ();
        if(response.status===200){
     
            return response;
        }
    },
    (error) => {
     
        hideLoading ();
        msag(error)
    }
);

export default {
     
    /**
     * 封装get方法
     * @param url  请求url
     * @param params  请求参数
     * @returns {Promise}
     */
    get(url, params = {
     }) {
     
        return new Promise((resolve, reject) => {
     
            axios.get(url, {
     
                params: params,
            }).then((response) => {
     
                resolve(response.data);
            })
                .catch((error) => {
     
                    msag(error);
                    reject(error);
                });
        });
    },

    /**
     * 封装post请求
     * @param url
     * @param data
     * @returns {Promise}
     */

    post(url, data) {
     
        return new Promise((resolve, reject) => {
     
            axios.post(url, data).then(
                (response) => {
     
                    //关闭进度条
                    resolve(response);
                },
                (err) => {
     
                    msag(err);
                    reject(err);
                }
            );
        });
    },

    /**
     * 封装patch请求
     * @param url
     * @param data
     * @returns {Promise}
     */
     patch(url, data = {
     }) {
     
        return new Promise((resolve, reject) => {
     
            axios.patch(url, data).then(
                (response) => {
     
                    resolve(response);
                },
                (err) => {
     
                    msag(err);
                    reject(err);
                }
            );
        });
    },

    /**
     * 封装put请求
     * @param url
     * @param data
     * @returns {Promise}
     */

    put(url, data = {
     }) {
     
        return new Promise((resolve, reject) => {
     
            axios.put(url, data).then(
                (response) => {
     
                    resolve(response);
                },
                (err) => {
     
                    msag(err);
                    reject(err);
                }
            );
        });
    }
}
//失败提示
function msag(err) {
     
   // hideLoading ()
    if (err && err.response) {
     
        switch (err.response.status) {
     
            case 400:
                message.error(err.response.data.non_field_errors);//此处实际情况修改
                break;
            case 401:
                message.error("未授权,请登录");
                break;

            case 403:
                message.error("拒绝访问");
                break;

            case 404:
                message.error("请求地址出错");
                break;

            case 408:
                message.error("请求超时");
                break;

            case 500:
                message.error("服务器内部错误");
                break;

            case 501:
                message.error("服务未实现");
                break;

            case 502:
                message.error("网关错误");
                break;

            case 503:
                message.error("服务不可用");
                break;

            case 504:
                message.error("网关超时");
                break;

            case 505:
                message.error("HTTP版本不受支持");
                break;
            default:
        }
    }
}
// 显示加载动画
function showLoading () {
     
    let dom = document.createElement('div');
    dom.setAttribute('id', 'loading');
    document.body.appendChild(dom);
    ReactDOM.render( <Spin size="large" >
        <div className='loading_box' />
    </Spin>, dom)
}
// 隐藏加载动画
function hideLoading () {
     
    document.body.removeChild(document.getElementById('loading'))
}
/**
 * 查看返回的数据
 * @param url
 * @param params
 * @param data
 */
function landing(url, params, data) {
     
    if (data.code === -1) {
     
    }
}

在一个组件中使用接口请求

import React, {
      Component } from 'react';
import Axios from '../../../components/request/axios'
class Header extends Component{
     
   componentDidMount() {
     
       Axios.post(//其他的方法仿照这个就行了
            '/api/xxx/',
            {
     username:'111',password:'222'}
            ).then((response)=>{
     
                console.log(response)//愉快的操作数据吧
        })
    }
     render() {
     
       return (<div></div>)
     }
}

五、antd默认样式配置问题

参考链接:
https://juejin.cn/post/6844904000668581902

设置好了重启才能生效,同时别忘了移除前面在 src/App.css 里全量添加的 @import ‘~antd/dist/antd.css’; 样式代码。不然也同样不生效。

如果启动报错,less和less-loader插件版本改为 [email protected] less-loader@ 5.0.0
已验证此方法有导致菜单hover时候,二级菜单弹不出问题,不建议使用

下面为新方法,已验证可使用,暂时没出问题
先安装两个插件

$ yarn add @craco/craco
$ yarn add craco-less

现在根目录下创建文件 craco.config.js,也就是项目文件夹下创建。

const CracoLessPlugin = require('craco-less');

module.exports = {
     
  plugins: [
    {
     
      plugin: CracoLessPlugin,
      options: {
     
        lessLoaderOptions: {
     
          lessOptions: {
     
            modifyVars: {
      '@primary-color': '#1DA57A' },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};

App.js文件引用 @import ‘~antd/dist/antd.less’,去掉css文件的引用

这里利用了 less-loader 的 modifyVars 来进行主题配置,变量和其他配置方式可以参考 配置主题 文档。修改后重启 yarn start,如果看到一个绿色的按钮就说明配置成功了。

antd 内建了深色主题和紧凑主题,你可以参照 使用暗色主题和紧凑主题 进行接入。

以上新方法为antd官网内容,更多修改及配置查看https://ant.design/docs/react/use-with-create-react-app-cn

你可能感兴趣的:(axios安装封装及使用,react跨域问题,react,javascript)