共计 4733 个字符,预计需要花费 12 分钟才能阅读完成。
记录一下 React 我的项目开发罕用 API,作为后续开发的参考。
路由配置
配置文件模式
// router/index.js
import 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.js
import {createHashHistory} from 'history'
export default createHashHistory()
import history from './history'
history.back()
款式编写
styled-components
// App.js
import {ThemeProvider} from 'styled-components'
// 传递主题
<ThemeProvider theme={{primaryColor: '#db3046'}}>
<Permission />
</ThemeProvider>
// index/style.js
import 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.js
import {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.actions
export default slice.reducer
注册模块
// store/index.js
import {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>
)
}
正文完