React-cra项目初始化 必做操作

990 阅读5分钟

创建好 Create React App dome 项目后完成如下操作, 让你的后续工作更丝滑

1 . 调整目录结构

├── src
│       ├── App.js         # 根组件
│       ├── index.css      # 全局样式
│       ├── index.js       # 项目入口
│   ├── api        # axios 请求 
│   ├── assets     # 项目资源文件,比如,图片 等
│   ├── components # 通用组件
│   ├── pages      # 页面
│   └── utils      # 工具,比如,token、axios 的封装等
└── package-lock.json

2 . 调整文件内容

import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
ReactDOM.render(
    <App />,
  document.getElementById('root')
)

3 . 配置路由

安装路由

react 脚手架并没有默认集成路由功能,需要单独安装。

安装路由 : npm i react-router-dom@5.3.0

注意 : 目前6.0.0以上版本的路由生态不完善, 占时不推荐使用

排期

按照页面A 和页面B 没有相同的部分,这两个页面就应该是一级路由的思路配置路由

    路由地址              ---------      页面组件
1级路由    
localhost:3000/layout     ----->  pages/Layout/Layout.jsx
localhost:3000/login      ----->  pages/Login/Login.jsx
localhost:3000/其他地址    ----->  pages/NotFound/NotFound.jsx

2级路由
localhost:3000/layout/questions -----> pages/Layout/Questions/Question.jsx
localhost:3000/layout/column -----> pages/Layout/Column /Column .jsx 
localhost:3000/layout/course -----> pages/Layout/Course /Course .jsx 
localhost:3000/layout/activity-----> pages/Layout/Activity/Activity.jsx 

创建必备组件

src
└── pages
    ├── Layout
    │   └── Layout.jsx
    ├── Login
    │   └── Login.jsx
    └── NotFound
        └── NotFound.jsx

配置路由组件

App.js 组件中

  • 导入路由组件
  • 导入页面组件
  • 配置路由规则
import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import Login from './pages/Login/Login.jsx'
import Layout from './pages/Layout/Layout.jsx'
import NotFound from './pages/NotFound/NotFound.jsx'
export default function App() {
  return (
    <Router>
      <div className="app">
        <Switch>
          <Route path="/login" component={Login}></Route>
          <Route path="/layout" component={Layout}></Route>
          {/* 增加一个404 */}
          <Route component={NotFound}></Route>
        </Switch>
      </div>
    </Router>
  )
}

4 . 配置第三方组件库 antd

下载依赖包

  • npm i antdyarn add antd

在 index.js 中导入 antd 的样式文件

// 在 index.js 中导入 antd 的样式文件
import 'antd/dist/antd.css'

5 . 二次封装 axios

下载依赖包

  • npm i axiosyarn add axios

在 utils 下建立 request.js 工具文件

完成如下配置 :

  • 配置基地址
  • 请求等待时间
  • 添加请求拦截器&响应拦截器
  • 导出 封装后的 axios
import axios from 'axios'

// baseURL设置/超时时间设置
const instance = axios.create({
  baseURL: 'http://xxx.xxx.xx', // 配置请求基地址
  timeout: 5000 // 配置等待时间
})

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  // 操作请求
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 操作响应
  return response.data
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error)
})

/**
 * @param {String} - url  请求地址
 * @param {String} - method  请求类型
 * @param {Object} - submitData  对象类型,提交数据
 */
const request = (url, method, submitData) => {
  return instance({
    url,
    method,
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
}

export default request

api/login.js 文件导入 request 封装 api

6 . sass的使用

注意:react 脚手架中已集成了sass 的配置,因此只需要安装 sass 的依赖包,就可以直接使用sass了

安装 sass 依赖包

  • npm i sass -Dyarn add

使用 :

  • index.css改成index.scss
  • 在组件中导入index.scss文件

7 . 修改 @ 为src路径

cra脚手架 中 修改 @ 为src路径

  • 下包 yarn add -D @craco/craco

  • 在项目根目录下,创建配置文件:craco.config.js

    // craco.config.js
    const path = require('path')
    module.exports = {
      webpack: {
        alias: {
          '@': path.join(__dirname, 'src') // 允许通过@符号来表示 src目录
        }
      }
    }
    
  • 修改 package.json 中的脚本命令

    // 将 start/build/test 三个命令修改为 craco 方式
    "scripts": {
      "start": "craco start",
      "build": "craco build",
      "test": "craco test",
      "eject": "react-scripts eject"
    },
    

注意 : eject 命令是强制释放所有配置,到react-scripts 文件中, 这个命令是不可逆的不推荐使用

8 . 使用 @ 后vscode 提示配置

  • 新建 jsconfig.json 文件

    {
    "compilerOptions": {
      "baseUrl": "./",
      "paths": {
        "@/*": ["src/*"]
      }
    }
    }
    

9 . 样式污染解决方法

前提 :

如果多个组件的样式中出现选择器重复,那么一个组件中的样式就会在另一个组件中也生效,从而造成组件之间样式相互覆盖的问题。

方法一 (不推荐)

给每个组件的根标签取不一样的类名

方法二 CSS IN JS (推荐使用)

CSS IN JS : 是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题

具体实现方法有50种(下述为常用的两种)

  • scoped : vue中默认使用 scoped css
  • CSS Moudles : React 中默认使用 CSS Moudles

10 . CSS Moudles 的使用

  • 在所有的css的文件名后缀前面加上 .moudle
  • 组件中, 导入 import styles from './xxx.module.scss
  • 组件中使用 : <div className={style.css类名}>

注意 :

  • CSS Moudles 最好使用 驼峰命名

  • 保持原有类名的语法 :global(.类名){样式}

    • 应用场景 : 修改别人已经封装好组件的类名(组件库-antd)

11 . CSS Modules 的简化用法

上述用法写类名有点麻烦

简化用法

  • 定义样式, 在根节点下用 :global {}包裹

  • 组件中使用方法

    • 根节点用 <div className={style.css类名}>
    • 子节点用 直接使用类名 className=css类名

12 . 配置 Redux

  • 安装 redux 相关的包:npm i redux react-redux redux-thunk redux-devtools-extension
  • 在 store 目录中分别创建:actions 和 reducers 文件夹、index.js 文件
  • 在 store/index.js 中,创建 store 并导出
  • 创建 reducers/index.js 文件,创建 rootReducer 并导出
  • 创建 reducers/login.js 文件,创建基础 login reducer 并导出
  • 在 src/index.js 中为 React 组件接入 Redux

store 目录结构:

├─store                # redux根目录
│  ├─actionTypes.js    # 
│  ├─reducers          # 
│  │  ├─index.js         # 
│  │  └─login.js       #  
│  ├─actions           # 
│  │  └─login.js       # 
│    └─index.js          # 创建store并导出

配置代码直接开箱即用

store/index.js 中:

import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'
import rootReducer from './reducers'const middlewares = composeWithDevTools(applyMiddleware(thunk))
const store = createStore(rootReducer, middlewares)
​
export default store

store/reducers/index.js 中:

import { combineReducers } from 'redux'import login from './login'const rootReducer = combineReducers({
  login
})
​
export default rootReducer

store/reducers/login.js 中:

const initValue = {
  token: ''
}
export default function login(state = initValue, action) {
  return state
}

src/index.js 中:

import { Provider } from 'react-redux'
import store from './store'ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

13 . AuthRoute 组件封装

实现 React 中路由权限控制

components/AuthRoute .js

import { hasToken } from '@/utils/storage'
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
// 我们需要解构所有的属性,除了component属性
export default function PrivateRoute(porps) {
   const Component = porps.component
  return (
    <Route
       {...porps}
      //path = {porps.path} 子组件内部没有 porps参数
      render={() => {
        if (hasToken()) {
          return <Component></Component>
        } else {
          return <Redirect to="/login"></Redirect>
        }
      }}
    ></Route>
  )
}

app.js

import PrivateRoute from './components/AuthRoute ' 
<PrivateRoute path="/home" component={组件名}></PrivateRoute>