React脚手架的创建和路由以及redux仓库的安装与应用

前言:学习react有一段时间了 始终感觉vite+react更舒服一点  但是奈何vite搭配react的各种插件包和脚手架有点差异 虽然vite方面也配置好了  但是感觉市场上 react脚手架似乎应用的更多一点,那就做下脚手架的笔记吧!

进入正题

1. node自带的npx 不用管

 npx create-react-app xxx

2.初始化一下 在启动看下

npm i 
npm start

3.开始下载插件的依赖了

npm i axios react-router-dom redux react-redux @reduxjs/toolkit

4.下载 less 或者sass预处理器 这里最好放在开发环境 打包后都是css 

npm i sass -D

5.先配置 react-router-don路由

        1.在src里面创建个router文件夹  再在里面创建index.js
        2.在这个index文件里 copy吧 改自己想要的效果  图二是路由懒加载 嫌麻烦就用图1
import {createBrowserRouter} from 'react-router-dom';
import XXX from '@/xxx/xxx'

// 创建路由表  这里没直接暴露出去 而是这样写 因为ESlint。。。
export const router = createBrowserRouter([
    {
        path: '/',
        element: <div>等</div>,
    },
    {
        path: '/home',
        element: <div>home</div>,
    },
    {
        path: '/sub',
        element: <div>Sub</div>,
    },
    {
        path: '/xxx',
        element: <XXX >xxx</XXX >,
    },
])
import {createBrowserRouter} from 'react-router-dom';
import { lazy } from 'react';
// import Home from '../view/Home/Home'
// import Login from '../view/Login/Login'

const Home = lazy(() => import('../view/Home/Home'));
const Login = lazy(() => import('../view/Login/Login'));

// 创建路由表
export const router = createBrowserRouter([
    {
        path: '/',
        element: <div>等</div>,
    },
    {
        path: '/home',
        element: <Home>home</Home>,
    },
    {
        path: '/login',
        element: <Login>Login</Login>,
    },
    
])

       

3,然后就是在src根文件index.js引入就完了  (这里连App.js都不需要了~)

import React from "react";
import ReactDOM from "react-dom/client";
import { router } from "./router";
// 通过路由渲染跟路由
import { RouterProvider } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  // <React.StrictMode>  这玩意是 【严格模式】StrictMode 会引发的组件重复执行  可以注掉的 !!!
  <RouterProvider router={router}></RouterProvider>
  // </React.StrictMode>
);

        4.这一步看个人喜好 改不改看自己 可忽略这一步

1.找到依赖node_modules里面的react-script里的webpack.config.js文件搜索alias配置项 添加下面代码后再重新启动项目npm start

alias: {
        "@":path.resolve('src'),
        // Support React Native Web
        // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
        'react-native': 'react-native-web',
        // Allows for better profiling with ReactDevTools
        ...(isEnvProductionProfile && {
          'react-dom$': 'react-dom/profiling',
          'scheduler/tracing': 'scheduler/tracing-profiling',
        }),
        ...(modules.webpackAliases || {}),
      },

2.配置代理    项目上线的时候是不需要的 这里看项目开发 具体情况再做调整

npm i http-proxy-middleware -D

      在src目录里面生成一个setupProxy.js文件

        

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
  app.use(
    createProxyMiddleware("/api", {
      target: "http://localhost:8080", //  这里看后端给你协议.域名.端口是多少就改成多少就行了
      changeOrigin: true, // 控制服务器接收 到的请求头中host字段的值
      pathRewrite: {'^/api':''} // 去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
    }),
  );
};

6.接下来引入Ant Design UI组件库

        1.下载ant包
npm install antd
        2.修改 app.js,引入 antd 的样式  组件中需要什么组件就引入(按需加载,这里我就更喜欢vite的配置了。。。)  
import 'antd/dist/reset.css';

        举个例子 

import { Button } from 'antd';

export default function Home() {
  return (
    <div>Home
      <Button type="primary">点我</Button>
    </div>
  )
}
        3.重置默认样式 (可用自己的 也可用这里的)

        

html {
  color: #000;
  overflow-y: scroll;
  overflow: -moz-scrollbars
}
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td {
  margin: 0;
  padding: 0
}

body,button,input,select,textarea {
  font: 12px arial
}

h1,h2,h3,h4,h5,h6 {
  font-size: 100%
}

em {
  font-style: normal
}

small {
  font-size: 12px
}

ul,ol {
  list-style: none
}

a {
  text-decoration: none
}

a:hover {
  text-decoration: underline
}


fieldset,img {
  border: 0
}

button,input,select,textarea {
  font-size: 100%
}

table {
  border-collapse: collapse;
  border-spacing: 0
}

img {
  -ms-interpolation-mode: bicubic
}

textarea {
  resize: vertical
}

7.然后就是配置数据仓库了

        1.在src目录里创建store目录 接着store里创建index.js
import {configureStore} from '@reduxjs/toolkit';
import useUserStore from './userinfoStore'

// 创建仓库并且暴露
export const store = configureStore({
    reducer:{
        useUserStore,
    }
})
       2.下面的代码是userinfoStore.js
import {createSlice} from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'useUserStore',
  initialState:{
    userInfo:1
  },
  reducers: {
    incremented(state,{value}){
        state.userInfo = value;
    },
    increment(state,val) {
      state.value++
    },
    decrement(state,val) {
      state.value--
    },
    incrementByAmount(state, action) {
      state.value += action.payload
    },
  },
})

// export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
        3.再将store引入index.js中
import React from "react";
import ReactDOM from "react-dom/client";
import { router } from "./router";
// 通过路由渲染跟路由
import { RouterProvider } from "react-router-dom";
import {store} from "./store";
import { Provider } from "react-redux";
import "antd/dist/reset.css";
import "./index.css";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  // <React.StrictMode>  这玩意是 【严格模式】StrictMode 会引发的组件重复执行  可以注掉的 !!!
  <Provider store={store}>
    <RouterProvider router={router}></RouterProvider>
  </Provider>
  // </React.StrictMode>
);
        4.接下来咋们看看试用例子

        home组件中使用数据仓库

        

import {useDispatch,useSelector} from 'react-redux';
import {Button} from 'antd'

export default function Login() {
    const dispatch = useDispatch()
    const user = useSelector((state)=>{
        return state.useUserStore.userInfo;
    });
    const users = (str='mm')=>{
        console.log(str,'str');
        //        type 仓库名称/方法                 参数
        dispatch({type:'useUserStore/incremented',value:100})
    }
  return (
    <div>Login -- {user}
        <Button onClick={users.bind(null,undefined)} type='primary'>点我赋值</Button>
    </div>
  )
}

8.最后配置axios的二次封装了

1.在src目录下创建required或者utils文件夹 再在里面创建request.js  我这里上面做了配置代理 所以这里baseURL注了  当项目上线还是得用这里的baseURL的  下面还有请求拦截和响应拦截  自己看业务需求来补就行了 用不着 errorCode  的可以自己注了  或者 自己写点json数据补就行了 

import axios from "axios";
import errorCode from "@/utils/errorCode";

//设置默认请求头
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// const BaseURL = "api";
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  // baseURL:
  //   process.env.NODE_ENV === "production"
  //     ? `/`
  //     : `http://dev.ktpark.net:9000/`, // 请求地址的基准路径

  /* http:"dev.ak.com"
  https:"pay.ak.com" */
  // 超时
  timeout: 3000, //请求超时时间(5秒后还未接收到数据,就需要再次发送请求)
  // retry: 1, //设置全局重试请求次数(最多重试几次请求)
  // retryDelay: 100, //设置全局请求间隔
});

// // 添加请求拦截器
// service.interceptors.request.use(config => {
//   // 在发送请求之前做些什么
//
//   return config
// }, error => {
//   // 对请求错误做些什么
//   return Promise.reject(error)
// })

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    console.log(response,'response');
    // const code = response.data.code || 200;
    const code = response.data.code || 200;
    // 获取错误信息
    const msg = errorCode[code] || response.data.msg || errorCode["default"];

    // 当返回不对劲错误信息  直接发送错误提示
    if (response.status === 200 && response.data?.data?.scanCode === -1) {
      return Promise.reject("error");
    }

    if (response.status === 500) {
      return Promise.reject(new Error(msg));
    } else if (response.status !== 200) {
      return Promise.reject("error");
    } else if (response.status === 200 && response.data?.code === -1) {
      return Promise.reject("error");
    } else {
      return response.data;
    }
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default service;

2.下面随便来点errorCode 的json数据

const errorCode = {
  '401': '认证失败,无法访问系统资源',
  '403': '当前操作没有权限',
  '404': '访问资源不存在',
  '500': '终端不在线',
  'default': '系统未知错误,请反馈给管理员'
}

export default errorCode;

3. 最后编写接口了!接口封装的方法非常多 但是我比较喜欢这种简单明了的风格的接口的

import getMSg from './index'  
//  这里一定要看 注释啊!  上面引入的是刚才编写的axios拦截封装啊  一定要看啊 不能傻逼一样说看不
//  懂!!!
// 默认地址
let pathUrl = '/api'
let wangyi = '/qqq'
//  上面两个变量看自己  看业务需求 有的后端和蔼可亲  不会搞这些多端对接  但是有时候总会避免不了这
//  种情况 对不对?
export const getmmsg = (params)=>{
    console.log(params,'params');
    //  上面的日志是可以注掉的 这里我只是为了方便调接口  查看是否有误 
    return getMSg({
        method:'get',
        url:wangyi+'/xxx/xxx',
        params
    })
}

export const postmmsg = (data)=>{
    return getMSg({
        method:'GET',
        url:pathUrl+'/ad/info',
        data
    })
}

4.调接口方面我就不写demo了  不能饭喂到嘴里对吧  hha  感谢曾经的leader那么耐心的带我~

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值