记录一下React我的项目开发罕用API,作为后续开发的参考。

路由配置

配置文件模式

// router/index.jsimport React, { lazy, Suspense } from 'react'// Suspense配合lazy实现懒加载const SuspenseComponent = Component => {  return (    <Suspense>      <Component></Component>    </Suspense>  )}const routes = [  {    path: '/',    element: SuspenseComponent(lazy(() => import('../pages/index/Index'))),  },  {    path: '/login',    element: SuspenseComponent(lazy(() => import('../pages/login/Login')))  },  {    path: '/list/:b',    element: SuspenseComponent(lazy(() => import('../pages/list/List')))  },  {    path: '*',    element: SuspenseComponent(lazy(() => import('../pages/notFound/NotFound'))),  },]export default routes

标签模式

import { HashRouter, Routes, Route } from 'react-router-dom'import Index from './pages/index/Index'import Login from './pages/login/Login'import NotFound from './pages/NotFound/NotFound'<React.StrictMode>  <HashRouter>    <Routes>      <Route path='/' element={<Index />}></Route>      <Route path='/login' element={<Login />}></Route>      <Route path='*' element={<NotFound />}></Route>    </Routes>  </HashRouter></React.StrictMode>

路由鉴权

import React, { Fragment } from 'react'import { useRoutes, Navigate, useLocation } from 'react-router-dom'import routes from './router'import { getToken } from './utils/auth'const Permission = () => {    const token = getToken()    const location = useLocation()    // 没有token,且不是拜访登录页,重定向到登录页    const toLogin = !token && location.pathname !== '/login'    function RenderRoutes() {        return useRoutes(routes)    }    return (        <Fragment>            { toLogin ? <Navigate to="/login" replace /> : <RenderRoutes /> }        </Fragment>    )}export default Permission

路由跳转,传参

标签跳转

import { Link } from 'react-router-dom'<Link to={{pathname: '/'}}>    <button>跳转</button></Link>

useNavigate跳转

import { useNavigate } from 'react-router-dom'const navigate = useNavigate()/**   * 三种路由传参形式  * 1、申明传参:/list/:id  * 2、地址栏传参: /list?id=1  * 3、state属性传参:state: { id: 1 }  */navigate('/List/3?a=2', {    state: { id: 1 }})

history跳转(后退、后退)

// history.jsimport { createHashHistory } from 'history'export default createHashHistory()import history from './history'history.back()

款式编写

styled-components

// App.jsimport { ThemeProvider } from 'styled-components'// 传递主题<ThemeProvider theme={{ primaryColor: '#db3046' }}>  <Permission /></ThemeProvider>
// index/style.jsimport styled from 'styled-components'export default styled.div`  height: 100vh;  display: flex;  flex-direction: column;  .nav {      height: 70px;      padding: 0 20px;      background-color: ${props => props.theme.primaryColor};      display: flex;      align-items: center;      .title {          text-align: left;          flex: 1;          font-size: 20px;          font-weight: 600;          color: yellow;      }  }`

状态治理

创立模块

// store/features/user.jsimport { createSlice, createAsyncThunk } from '@reduxjs/toolkit'import { getToken, getUserInfo, removeToken, removeUserInfo } from '../../utils/auth'import { logout } from '../../api/login'import history from '../../lib/history'export const logoutAction = createAsyncThunk('user/logout', async () => {  return await logout()})const slice = createSlice({  name: 'user',  initialState: {    token: getToken(),    userInfo: getUserInfo(),  },  reducers: {    setToken(state, { payload }) {      state.token = payload    },    setUserInfo(state, { payload }) {      state.userInfo = payload    },  },  extraReducers(builder) {    builder.addCase(logoutAction.fulfilled, (state, { payload }) => {      if (payload.success && payload.code === 200) {        state.token = ''        state.userInfo = ''        removeToken()        removeUserInfo()        history.push('/login')        location.reload()      }    })  },})export const { setToken, setUserInfo } = slice.actionsexport default slice.reducer

注册模块

// store/index.jsimport { configureStore } from '@reduxjs/toolkit'import userReducer from './features/user'export default configureStore({  reducer: {    user: userReducer  }})

传递状态

import { Provider } from 'react-redux'import store from './store/index'import App from './App'<Provider store={store}>  <App /></Provider>

获取、操作状态

import { useSelector, useDispatch } from 'react-redux'import { logoutAction } from '../../store/features/user'const { userInfo } = useSelector(store => store.user)const dispatch = useDispatch()return (  <div>    <div>{userInfo.realName}</div>    <button onClick={() => dispatch(logoutAction())}>登出</button>  </div>)

函数组件应用钩子

import React, { useState, useEffect } from 'react'function onRequest() {}const [number, setNumber] = useState(0)/** * useEffect第二个参数不传,任意状态产生扭转,都会执行 * 传[],只在组件挂载后执行 * 传[number],在组件挂载后和number变动后执行 */useEffect(() => {    onRequest()}, [number])

代码优化

缩小反复渲染

memo

// 调用memo,当父组件从新渲染,然而props不变时,子组件读取缓存import React, { memo } from 'react'const Child = () => {  return (    <div>child</div>  )}export default memo(Child)

useCallback

// 应用useCallback处理函数,当父组件从新渲染,依赖数组不变时,返回雷同函数,防止触发props变动,导致子组件从新渲染import React, { useState, useCallback } from 'react'import Child from 'Child'const Parent = () => {  const [value, setValue] = useState(0)  function sum() {    setValue(value + 1)  }  const sumCall = useCallback(sum, [])  return (    <div>      <div>{ value }</div>      <Child onClick={sumCall} />    </div>  )}

缩小反复计算

useMemo

// 调用useMemo,当组件从新渲染时,若依赖数组不变,间接读取缓存的后果import React, { useMemo, useState } from 'react'const Parent = () => {  const [value, setValue] = useState(0)  function sum() {    let result = 0    for(let i = 0; i < 100000; i++) {      result++    }    return result  }  const result = useMemo(sum, [])  return (    <div>      <div>{ value + result }</div>      <button onClick={() => setValue(value + 1)}></button>    </div>  )}