搭建React项目

一、项目构建

安装脚手架

npm install -g create-react-app
// or
yarn add -g create-react-app

 创建项目

创建一个新文件夹my-react-app,并在该文件夹下使用终端创建项目my-react-app

create-react-app my-react-app --template typescript

使用vscode打开刚创建的项目,可以看到项目结构:

react项目默认隐藏了webpack相关配置,执行

npm run eject

 暴露webpack配置,此操作不可撤销,请按需要操作。

此时,项目已经创建完成,运行

npm run start

 浏览器中可以看到

配置路径别名

这里我们使用craco来配置路径别名,安装craco:

npm i @craco/craco
// or
yarn add @craco/craco

修改package.json中的启动脚本:

"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

在项目的根目录中创建craco.config.js,并配置路径别名:

const path = require('path')

module.exports = {
  webpack: {
    alias: {
      '@': path.resolve(__dirname, 'src/'),
    },
  },
}

并在tsconfig.json中增加配置:

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

二、引入 Ant Design 组件库

安装和初始化

Ant Design官网:https://ant-design.antgroup.com/index-cn

使用脚手架

$ npx create-react-app antd-demo --template typescript
// or
$ yarn create react-app antd-demo --template typescript

引入 antd

npm install antd --save
// or
yarn add antd

改造App.tsx

import React from 'react'
import { ConfigProvider, Button } from 'antd'
import dayjs from 'dayjs'
import zhCN from 'antd/locale/zh_CN'
import './App.css'

dayjs.locale('zh-cn')

const App: React.FC = () => {
  return (
    <ConfigProvider locale={zhCN}>
      <div className='App'>
        <Button type='primary'>欢迎</Button>
      </div>
    </ConfigProvider>
  )
}

export default App

在页面上看到欢迎按钮,引入成功。

 三、路由配置

React Router 官网:https://reactrouter.com/en/main

安装 React Router

npm install react-router-dom
// or
yarn add react-router-dom

使用路由 

改造根目录 index.tsx,这里使用 BrowserRouter:

import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import reportWebVitals from './reportWebVitals'
import { BrowserRouter } from 'react-router-dom'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()

在src下新增页面:

在src下增加router/index.tsx:

import { Navigate } from 'react-router-dom'
import Home from '@/pages/home'
import Login from '@/pages/login'
import Layout from '@/pages/layout'

const routes = [
  {
    path: '/login',
    element: <Login />,
  },
  {
    path: '/',
    element: <Navigate to='/login' />,
  },
  {
    path: '/layout',
    element: <Layout />,
    children: [
      {
        path: '/layout/home',
        element: <Home />,
      },
    ],
  },
]

export default routes

改造App.tsx

import React from 'react'
import { ConfigProvider } from 'antd'
import dayjs from 'dayjs'
import zhCN from 'antd/locale/zh_CN'
import './App.css'
import routes from '@/router'
import { useRoutes } from 'react-router-dom'

dayjs.locale('zh-cn')

const App: React.FC = () => {
  const elements = useRoutes(routes)

  return (
    <ConfigProvider locale={zhCN}>
      <div className='App'>{elements}</div>
    </ConfigProvider>
  )
}

export default App

四、配置 axios

安装 axios

npm install axios -S

配置 axios

在src下新建文件src/api/http.ts

import axios from 'axios'

const service = axios.create({
  timeout: 60 * 1000,
  // 基础接口地址
  baseURL: '',
  headers: { 'Content-Type': 'application/json;charset=UTF-8' },
})

service.interceptors.request.use(config => {
  const token = localstorage.getItem('', 'user_token')
  config.headers['x-auth-token'] = token
  return config
})

service.interceptors.response.use(
  response => {
    return response.data
  },
  err => {
    if (err?.response?.data?.code === '000401') {
      window.location.href = '/login'
    }
    return Promise.reject(err)
  }
)

export default service

五、配置 Redux 并持久化

Redux中文网:https://www.redux.org.cn/

安装 Redux Toolkit 和 React-Redux

npm install @reduxjs/toolkit react-redux

安装 redux-persist

npm install redux-persist --save

配置 Redux

在src文件夹下创建src/store/index.ts:

import { configureStore } from '@reduxjs/toolkit'

import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'

import rootReducer from './reducer'

const persistConfig = {
  key: 'root',
  storage,
  whitelist: [], // 这里存放白名单
}

const store = configureStore({
  reducer: persistReducer(persistConfig, rootReducer),
  middleware: getDefaultMiddleware =>
    getDefaultMiddleware({
      serializableCheck: false,
    }),
})

export const persistor = persistStore(store)

export default store

// 从 store 本身推断出 `RootState` 和 `AppDispatch` 类型
export type RootState = ReturnType<typeof store.getState>
// 推断出类型: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

src/store/reducer.ts:

import { combineReducers } from '@reduxjs/toolkit'

const rootReducer = combineReducers({})

export default rootReducer

改造根目录的index.tsx:

import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import { BrowserRouter } from 'react-router-dom'
import reportWebVitals from './reportWebVitals'
import store from './store'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import { persistor } from './store'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </PersistGate>
    </Provider>
  </React.StrictMode>
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()

在src文件夹下创建src/hooks/redux.ts:

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from '@/store/index'

export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

以用户登录成功后设置用户信息为例,在src文件夹下创建src/store/slices/user.ts:

import { createSlice, PayloadAction } from '@reduxjs/toolkit'

interface UserState {
  userInfo: any
  token: string
}

const initialState: UserState = {
  userInfo: {},
  token: '',
}

export const userSlice = createSlice({
  name: 'user',
  initialState: initialState,
  reducers: {
    setUserInfo(state, action) {
      state.userInfo = action.payload
    },
    setToken(state, action: PayloadAction<string>) {
      state.token = action.payload
    },
  },
})

export const { setUserInfo, setToken } = userSlice.actions

export default userSlice.reducer

在src/store/reducer.ts中添加:

import { combineReducers } from '@reduxjs/toolkit'
import userReducer from './slices/user'

const rootReducer = combineReducers({
  user: userReducer,
})

export default rootReducer

在src/pages/login/index.tsx中:

import React, { useState } from 'react'
import { useAppDispatch } from '@/hooks/redux'
import { setUserInfo, setToken } from '@/store/slices/user'

const Login: React.FC = () => {
  const dispatch = useAppDispatch()
  
  const onFinish = () => {
    /*...一些代码...*/
    dispatch(setUserInfo(user))
    dispatch(setToken(token))
    /*...一些代码...*/
  }

  return (
    <div>{/*...一些代码...*/}</div>
  )
}

export default Login

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值