react 組件開發基礎
-
組件分類與組件使用
-
組件傳參
-
父傳子 【函數數據傳值 實參 形參對應關系】
-
子傳父
-
插槽
-
透傳 useContext 上下文(作用域)
-
跨層級調用方法 通過子組件的實例對象useRef 直接調用子組件的方法 和數據
-
-
狀態管理(非常多) useReducer
-
redux
-
redux-toolkit 最佳實踐
-
mobx
-
dva
-
-
路由 react-router-dom
-
配置式 路由 router.jsx
-
將路由的代碼 直接寫入到 父組件里面
-
-
UI 庫 :antd 管理系統 antd mobile 移動端 app nutUi+taro 小程序
1.組件分類與組件使用
組件分類:
? 頁面級組件
? 業務組件
? 公共組件
組件使用步驟: 1創 2導 3使用 4傳值、
組件名: 必須使用大駝峰
-
父組件
?import React from 'react'// 導入import AppHeader from '@/components/appHeader/AppHeader'export default function App() {return (<><AppHeader/><AppHeader> </AppHeader></>)}?
-
子組件
import React from 'react'import './index.less'export default function AppHeader() {return (<div>AppHeader</div>)}?
2.組件通信【單向數據流】
1.父傳子 子傳父
react 的組件就是一個普通函數
父傳子
組件使用: 父函數 調用 子函數
父組件 寫入實參
子組件 通過形參接受數據
-
父組件
父組件 寫入實參: 通過 靜態屬性 或動態屬性 傳遞
import Child from '@/components/child/Child'?export default ()=>{return (<Child title="我是爸爸傳遞的數據" num={1000} ? obj={name="張麻子"}> </Child>)}??
-
子組件
子組件通過形參 props 全部一次性接收父組件傳遞的數據
export default (props)=>{let {num,title,obj} = props;if(typeof num !='Number'){return 'num的數據格式錯誤'}if(Object.prototype.toString.call(obj) !='[object Object]'){return 'obj數據格式錯誤!'}return (<><div>我是兒子組件</div>{props.num}{obj.name}</>)}
2.子傳父
將父組件的方法 傳遞給子組件
子組件調用這個方法 直接修改父組件的數據
-
父組件
import Child from '@/components/child/Child'?export default ()=>{const [num,setNum] = useState(1000)const changeNum=(newNum)=>{setNum(newNum)}return (<Child title="我是爸爸傳遞的數據" num={num} changeNum={changeNum} ? obj={name="張麻子"}> </Child>)}
-
子組件
?export default (props)=>{const {num,title,obj,changeNum} = props;return (<><div>我是兒子組件</div>{props.num}{obj.name} ??<button οnclick={()=>changeNum(num+1) > +++</button></>)
3.插槽
父組件 將 html 代碼 傳遞給子組件
父組件 傳遞給子組件的html代碼 全部會自動的 放到
props.children
props.children 值
如果父組件沒有傳遞html代碼 ,children 的值 是
undefined
如果父組件只傳遞了 一行html代碼 ,children 的值 就是一個對象(描述傳遞過來的html jsx )
如果父組件傳遞了 多行html代碼,children的值 就是 一個數組(包含多個對象)
-
父組件
<h1>我是爸爸組件的html代碼</h1><hr /><Son ><div>我是爸爸組件傳遞給兒子組件的 html代碼</div><table><thead><tr><th>姓名</th><th>年齡</th><th>成績</th></tr></thead><tbody><tr><td>嘻嘻嘻</td><td>22</td><td>88</td></tr></tbody></table></Son>
-
子組件
import React from 'react'?export default function Son(props) {const {children} = propsreturn (<> ? ? ?{children[1]}<h1>我是兒子組件自己的html代碼</h1>{children[0]}</>)}?
4.透傳 useContext createContext 上下文(作用域)
爺爺組件 可以直接傳遞數據 給孫子組件
跨層級 不限制
vue2 $bus eventBus 中央事件總線
-
爺爺組件
商品信息 傳遞 --商品列表 Goods.jsx
import {createContext,useState} from 'react'import Info from '@/components/info/Info'//在頂級組件 暴露之前必須定義好 上下文export const GoodsContext = createContext(null);?export default ()=>{const [goodsInfo,setGoodsInfo] = useState({id:1122,title:'華為收集 mate6',price:5000})const changeGoodsInfo = ()=>{let goods = {...goodsInfo}goods.price++setGoodsInfo(goods)}return (<><GoodsContext.Provider value={goodsInfo}><Info /></GoodsContext.Provider>?<button onClick={changeGoodsInfo}>+</button></>)}?
-
爸爸組件 Info.jsx
商品詳情組件
import Order from '@/components/order/Order'export default ()=>{return (<><div>爸爸組件自己的內容</div><Order /></>)}
-
孫子組件 Order.jsx
下單組件
import {useContext} from 'react'import {GoodsContext} from '@/App2'export default ()=>{const goodsInfo = ?useContext(GoodsContext)return (<><div> 價格:{goodsInfo.price} </div></>)}
5.子組件的實例對象useRef useImperativeHandle
父組件 需要拿子組件的數據
-
父組件
import Son1 from '@/components/son1/Son1'import {useRef,useEffect} from 'react'export default ()=>{const sonRef = useRef(null);useEffect(()=>{let res = ?sonRef.current.getData()console.log(res);},[])return (<><div >爸爸組件自己的內容</div><Son1 ref={sonRef} /></>)}
-
子組件
useImperativeHandle : 通過hoos 將子組件 想要暴露給 父組件的 方法和數據 暴露出去
import {useState,useImperativeHandle} from 'react'?export default ({ref})=>{const [num,setNum] = useState(100)const getData = ()=>{return '我是子組件的方法,獲取數據的方法'}const changeNum = ()=>{setNum(num+1)}// 需要子組件通脫useImperativeHandle(ref,()=>{return {num,getData,} })?return (<><div> 價格:{num} </div><button onClick={changeNum}>+ </button></>)}
-
localStorage sessionStorage
6.路由 react-router v7
react 19 ===router v7
react16.8--react 18 ====router v6
react13-react16.8 ===reouterv5
1.創 2配 router.jsx 3.占位 4.測試
-
安裝
pnpm install react-router
-
創建頁面
-
router/index.jsx
import {createBrowserRouter} from "react-router";import Home from '@/pages/home/Home'import Coding from '@/pages/coding/Coding'import Pins from '@/pages/pins/Pins'import Course from '@/pages/course/Course'import App from '@/App.jsx'import Following from '@/pages/following/Following'import Frontend from "@/pages/frontend/Frontend";const router = createBrowserRouter([{path:'/',Component:App,children:[{Component:Home,children:[{index:true,Component:Following},{path:'frontend',Component:Frontend},]},{path: "coding",Component:Coding},{path: "pins",Component:Pins},{path: "course",Component:Course}]}]);?export default router
-
main.jsx
?import { createRoot } from 'react-dom/client'import './index.css'?import { RouterProvider} from "react-router";import router from './router'?createRoot(document.getElementById('root')).render(<RouterProvider router={router}> </RouterProvider>)?
-
占位
App.jsx 給所有一級路由占位
import React from 'react'import { Outlet } from 'react-router'export default function App() {return (<><div>我是頂部</div><Outlet/></>?)}?
Home.jsx 給 home子頁面占位
import React from 'react'import { Outlet } from 'react-router'export default function Home() {return (<><div className="left">左側菜單</div><div className="content"><Outlet></Outlet></div><div className="toplist">排行榜</div></>)}?