flushSync強制刷新
如果不強制刷新是這樣:每次count在下一輪才更新
import { useState, useRef } from 'react'
import { flushSync } from 'react-dom'function App() {const [count, setCount] = useState(0)const ref=useRef(null)const handleClick = () => { setCount(count + 1)console.log(ref.current.innerHTML)}return (<div><button onClick={handleClick}></button><div ref={ref}>{count}</div></div>)
}export default App;
引入強制刷新:
import { useState, useRef } from 'react'
import { flushSync } from 'react-dom'function App() {const [count, setCount] = useState(0)const ref=useRef(null)const handleClick = () => { flushSync(() => { setCount(count + 1)console.log(ref.current.innerHTML)})}return (<div><button onClick={handleClick}></button><div ref={ref}>{count}</div></div>)
}export default App;
react自動進行批處理,一次按按鈕修改兩次count,最終一起渲染,叫自動批處理
import { useState } from 'react'
import { flushSync } from 'react-dom'function App() {const [count, setCount] = useState(0)const [count1, setCount1] = useState(0)const handleClick = () => { flushSync(() => { setCount(count + 1)setCount1(count1 + 1)})console.log('修改了一次')}return (<div><button onClick={handleClick}>按鈕</button><div >{count},{count1}</div></div>)
}export default App;
使用error boundary捕獲渲染錯誤
例如在App組件里調用了Head組件,如果Head組件出錯的話,正常情況是會影響整個界面的渲染的
我們想要的效果是當Head組件出錯時,單獨拋出Head組件的問題,并且不影響其他組件執行,需要用到一些第三方庫:react-error-boundary
下載
# npm
npm install react-error-boundary# pnpm
pnpm add react-error-boundary# yarn
yarn add react-error-boundary
使用方法
<ErrorBoundary fallback={<div>Something went wrong</div>}><ExampleApplication />
</ErrorBoundary>
如果Head還出錯,也不會影響其他組件的渲染,并且打印Head的錯誤
懶加載
用到的時候再加載,不用的時候不加載,節省性能
//App.jsx
import MyHead from './MyHead.jsx'
function Head() {return (<div><h1>頭部</h1></div>)
}function App() {return (<div>{/* <MyHead /> */}</div>)
}export default App;
//MyHead.jsx
console.log('MyHead.jsx is running...');function MyHead() {return (<div><h1>My Head</h1></div>);
}
export default MyHead;
如果引入組件不使用組件,組件還是會加載一遍的
如果在用戶沒用到這些組件的時候就加載,會大大滴降低性能
import{useState,lazy,Suspense }from 'react'const MyHead = lazy(() => import('./MyHead.jsx'))
//lazy需要接收一個promise對象,import()返回的是一個promise對象,符合lazy的要求,且語句執行到這里時,不加載
//使用時才加載
function App() {const [show,setShow]=useState(false)return (<div><button onClick={() => setShow(true)}>點擊我觸發MyHead</button><Suspense fallback={<div>loading</div> } >{show&&<MyHead/>}</Suspense ></div>)
}export default App;
這樣就只會在觸發MyHead按鈕的時候顯示MyHead組件了
點擊按鈕如果網速過慢,還可以顯示loading的過程:
createPortal渲染Dom的不同部分
作用是將子組件渲染到 DOM 樹中的指定節點,而不是父組件的 DOM 結構中
import {createPortal} from 'react-dom'
function App() {return (<div>{createPortal( <p>這是一個段落</p>,document.querySelector('body'))}</div>)
}export default App;
結構如下
可以用createPortal
將模態框渲染到?body
?節點,避免受到父組件樣式的影響。
<Profiler>和ReactDevTools的性能測試
import { useState ,Profiler} from "react"
function Head({count}) {return (<div>
hello Head{count}</div>)
}
function App() {const [count, setCount] = useState(0)const onRender = (id, phase, actualDuration, baseDuration, startTime, commitTime, interactions) => { console.log(id, phase, actualDuration, baseDuration, startTime, commitTime, interactions)}return (<div><button onClick={() => { setCount(count + 1) }}>點擊</button>{count}<Profiler id='Head' onRender={onRender}>{/* {需要id屬性,確認你要測試的是哪個組件} */}<Head count={count} /></Profiler></div>)
}export default App;
每次?Head
?組件渲染時,onRender
?回調函數都會被調用,并打印性能數據到控制臺。
總之就是用作分析性能的
hydrateRoot水合與服務的API
CSS-in-JS可以在js里寫css
下個庫
npm install styled-components
使用庫
import styled from 'styled-components'
const Div = styled.div`
width:200px;
height:200px;
background-color:red;
`
const Link = styled.a`
text-decoration:underline;
color:red`
function App() {return (<div><Div /><Link>去百度</Link></div>)
}
export default App
給Link里的鏈接加上偽類選擇器
const Link = styled.a`
text-decoration:underline;
color:red
&:hover{}`
鼠標hover上去會變黃色
import styled from 'styled-components'
const Div = styled.div`
width:200px;
height:200px;
background-color:red;
`
const Link = styled.a`
text-decoration:underline;
color:red;
&:hover{
color:yellow;
}`
function App() {return (<div><Div /><Link href='https://www.baidu.com'>去百度</Link></div>)
}
export default App
如果前面不加&,就是給Div的子類添加hover
import styled from 'styled-components'
const Div = styled.div`
width:200px;
height:200px;
background-color:red;p{
color:blue;
}
`
const Link = styled.a`
text-decoration:underline;
color:red;
&:hover{
color:yellow;
}`
function App() {return (<div><Div><p>嘻嘻嘻我是p</p> </Div ><Link href='https://www.baidu.com'>去百度</Link></div>)
}
export default App
控制display屬性,使用模板字符串
import { useState } from 'react'
import styled from 'styled-components'
const Div = styled.div`
width:200px;
height:200px;
display:${({show})=>show?'block':'none'};
background-color:red;p{
color:blue;
}
`
const Link = styled.a`
text-decoration:underline;
color:red;
&:hover{
color:yellow;
}`
function App() {const [show,setShow]=useState(true)return (<div><button onClick={() => setShow(!show)}>切換顯示</button><Div title='hello world' show={show}><p>嘻嘻嘻我是p</p> </Div ><Link href='https://www.baidu.com' >去百度</Link></div>)
}
export default App
React里使用TailwindCSS
彈幕說這個很好用
使用 Vite 安裝 Tailwind CSS - Tailwind CSS
行吧我沒學會用就這樣吧
喝了小酒我又回來了
//index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
//App.jsx
export default function App() { return (<h1 className="text-3xl font-bold underline">Hello, Vite!</h1>);
}
//vite配置
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'// https://vite.dev/config/
export default defineConfig({plugins: [react(), tailwindcss()],})
react-spring動畫庫
pmndrs/react-spring: ?? A spring physics based React animation library
# Install the entire library
npm install react-spring
# or just install your specific target (recommended)
npm install @react-spring/web
import { useState } from 'react'
import { useSpring, animated } from "@react-spring/web";const FadeIn = ({ isVisible, children }) => {const styles = useSpring({opacity: isVisible ? 1 : 0,y: isVisible ? 0 : 24,})return <animated.div style={styles}>{children}</animated.div>
}
function App() {const [isVisible, setIsVisible] = useState(true)return (<div><button onClick={()=>setIsVisible(!isVisible) }></button><FadeIn isVisible={isVisible}>hello App</FadeIn></div>)
}
export default App;
可以實現淡入淡出的效果
import { useState } from 'react'
import { useSpring, animated } from "@react-spring/web";const FadeIn = ({ isVisible, children }) => {const styles = useSpring({opacity: isVisible ? 1 : 0,y: isVisible ? 0 : 24,})return (<animated.div style={styles}>{children}<animated.span>{ styles.y.to((val) => val.toFixed(0))}</animated.span></animated.div>)
}
function App() {const [isVisible, setIsVisible] = useState(true)return (<div><button onClick={()=>setIsVisible(!isVisible) }></button><FadeIn isVisible={isVisible}>hello App</FadeIn></div>)
}
export default App;
點擊以后數字會改變
Ant Design Charts圖表庫和echarts for react
zustnd 小浣熊
算了加載不出來
蚊子咬學長推了這個echarts for react
import React, { useEffect } from 'react';
import ReactECharts from 'echarts-for-react';const MyChart = () => {// 這里定義圖表的 option 配置const getOption = () => ({title: {text: 'ECharts 示例',},tooltip: {},xAxis: {data: ['A', 'B', 'C', 'D', 'E'],},yAxis: {},series: [{name: '銷量',type: 'bar',data: [5, 20, 36, 10, 10],},],});// 處理圖表準備完畢的回調const onChartReadyCallback = () => {console.log('Chart is ready');};// 處理圖表事件const EventsDict = {click: (params) => {console.log('Chart clicked', params);},};return (<div><ReactEChartsoption={getOption()}notMerge={true}lazyUpdate={true}theme="light"onChartReady={onChartReadyCallback}onEvents={EventsDict}opts={{ renderer: 'canvas' }} // 你可以設置更多選項/></div>);
};export default MyChart;
React-BMapGL地圖庫
React-BMapGL文檔