记录一下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> )}