reactive
一、跨层级传递
import { useContext, createContext, useState } from "react"
const msgContext = createContext()
function A(){
const m = useContext(msgContext)
return (
<div>
A-{m}
<B></B>
</div>
)
}
function B(){
const m = useContext(msgContext)
return (
<div>B-{m}</div>
)
}
function App(){
const message = 'my name is msg'
return (
<div>
<msgContext.Provider value={message}>
<A ></A>
</msgContext.Provider>
</div>
)
}
export default App
二、useEffect
function App(){ const [num,setNum] = useState(0) // 没有依赖项[],初始+组件更新,会执行 // 空数组[],初始,会执行 // 传入依赖项,初始+依赖项,会执行 useEffect(()=>{ console.log("副作用函数执行了") },[num]) return ( <div> <button onClick={()=>{setNum(num+1)}}>{num}</button> </div> ) }
三、清除副作用
function Son () { useEffect(()=>{ const timer = setInterval(()=>{ console.log("定时任务执行中...") },1000) // 清除副作用 return () => { clearInterval(timer) } },[]) return <div>this is son</div> } function App () { // 通过条件渲染模拟组件卸载 const [show, setShow] = useState(true) return ( <div> {show && <Son />} <button onClick={() => setShow(false)}>卸载Son组件</button> </div> ) }
四、自定义hook
函数名称用以use打头
function useToggle(){ const [show, setShow] = useState(true) const toggle = () => setShow(!show) return { show, toggle } } function App () { const {show,toggle} = useToggle() return ( <div> {show && <div>is dispaly</div>} <button onClick={toggle}>卸载Son组件</button> </div> ) }

五、redux
npx create-react-app react-redux
npm i @reduxjs/toolkit react-redux
目录结构

counterStore.js
import { createSlice } from "@reduxjs/toolkit";
const createrStore = createSlice({
name: 'counter',
initialState: {
counte: 10
},
reducers: {
add(state){
state.counte++
},
jian(state){
state.counte--
}
}
})
const {add,jian} = createrStore.actions
const counterReducer = createrStore.reducer
export {add,jian}
export default counterReducer
state/index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore"
const store = configureStore({
reducer: {
counter: counterReducer
}
})
export default store
index.js
import store from './store' import { Provider } from 'react-redux'; <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>
App.js
import { useSelector,useDispatch } from "react-redux"
import { add,jian } from "./store/modules/counterStore"
function App () {
const {counte} = useSelector(state => state.counter)
const dispath = useDispatch()
return (
<div>
{counte}
<button onClick={()=>dispath(add())}>+</button>
<button onClick={()=>dispath(jian())}>-</button>
</div>
)
}
export default App
传参数
action.payload 接收参数
addToNum(state,action){ state.counte = action.payload },
异步
conterState.js
reducers: { updateLs(state,action){ state.ls = action.payload } } // 异步 const {updateLs} = createrStore.actions const url = 'http://geek.itheima.net/v1_0/channels' const getGeek = () => { return async (dispatch) => { const res = await axios.get(url) dispatch(updateLs(res.data.data.channels)) } } // 导出 export {getGeek}
app.js
import { useSelector, useDispatch } from "react-redux"
import { getGeek } from "./store/modules/counterStore"
import { useEffect } from "react"
const { ls } = useSelector(state => state.counter)
const dispath = useDispatch()
useEffect(()=>{
dispath(getGeek())
},[dispath])
<div>{
ls.map(item=><div key={item.id}>{item.name}</div>)
}
</div>
六、router
配置
npm i react-router-dom

Login/index.js
const Login = ()=>{ return <div> Login... </div> } export default Login
router/index.js
import Login from '../page/Login' import Article from '../page/Article' import { createBrowserRouter } from 'react-router-dom' const router = createBrowserRouter([ { path: '/login', element: <Login/> }, { path: '/article', element: <Article/> }, ]) export default router
index.js
import router from './router'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <RouterProvider router={router}></RouterProvider> </React.StrictMode> );
声明式路由、编程式路由
import { Link,useNavigate } from "react-router-dom"
const Login = () => {
const navigate = useNavigate()
return (
<div> Login...
{/* 声明式导航 */}
<Link to='/article'>link to</Link>
{/* 编程式导航 */}
<button onClick={()=>navigate('/article')}>编程式导航</button>
</div>
)
}
export default Login
22
?
// page01 <button onClick={()=>navigate('/article?id=2&name=tom')}>编程式1</button> // page02 import { useSearchParams,useParams } from "react-router-dom" const [params] = useSearchParams() let id = params.get('id')
/
// page01 <button onClick={()=>navigate('/article/123')}>编程式导航2</button> // page02 import { useSearchParams,useParams } from "react-router-dom" const params2 = useParams() let id2 = params2.id // router/index.js const routdr = createBrowserRouter([ { path: '/article/:id', element: <Article/> }, ])
嵌套路由

默认渲染二级路由

import { Link,Outlet } from "react-router-dom"
const Layout = ()=>{
return (
<div>
<div>Layout</div>
{/* 根目录默认渲染二级路由 */}
<Link to='/'>login</Link>
<br></br>
<Link to='/article'>article</Link>
<Outlet></Outlet>
</div>
)
}
export default Layout
404

两种路由模式

七、安装包
npm i @reduxjs/toolkit react-redux react-router-dom dayjs classnames antd-mobile axios
npm i D sass
npm i lodash
npm install normalize.css
# react 18 版本
npm i react-quill@2.0.0-beta.2 --legacy-peer-deps
八、配置联想提示路径

npm i D @craco/craco
craco.config.js
const path = require('path')
module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname,'src')
}
}
}
jsconfig.js
{ "compilerOptions": { "baseUrl": "./", "paths": { "@/*": [ "src/*" ] } } }
"scripts": {
"start": "craco start",
"build": "craco build",
}
九、json-server

十、配置主题

<Button color="primary">11</Button>
十一、index.js 配置
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; // import App from './App'; import { RouterProvider } from 'react-router-dom'; import router from './router'; import { Provider } from 'react-redux'; import store from './store'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> <RouterProvider router={router}></RouterProvider> </Provider> // <App /> );
十二、富文本编辑器
import ReactQuill from 'react-quill' import 'react-quill/dist/quill.snow.css' {/* //富文本 */} <ReactQuill className="publish-quill" theme="snow" placeholder="请输入文章内容" /> .publish-quill { .ql-editor { min-height: 300px; } }

浙公网安备 33010602011771号