react
react,Api分为 组件类 工具类 hooks react-dom 一共四个方向,加以讨论:
组件类
组件类分为三种类型:
- 继承基类的组件:
ComponentPureComponent - 高阶组件:
memoforwardRef - 内置的组件:
FragmentStrictModeSuspenseProfiler(这个是React Developer Tools内置组件)
Component
Component是class组件的根基.类组件的一切始于Component
ts
class Index extends React.Component{
constructor(props){
super(props)
this.state={
data:{
name:'alien',
age:28
}
}
}
handerClick= () =>{
const { data } = this.state
data.age++
this.setState({ data })
}
render(){
const { data } = this.state
return <div className="box">
<div className="show" >
<div> 你的姓名是: { data.name } </div>
<div> 年龄: { data.age }</div>
<button onClick={ this.handerClick } >age++</button>
</div>
</div>
}
}PureComponet
PureComponet被称为纯组件,使用方法跟Component一样,作用是避免不必要的render,提高性能;
memo
memo跟PureComponet类似;作用是用于函数式组件;也是避免不必要的render,对于props进行浅比较也就是使用Object.is比较;
未使用memo的版本:
react更新组件的机制导致react内部无法知道那个组件跟新,所以会出现组件props未变化,但是组件进行重新render的情况: 
tsx
import { FC, useState } from "react"
function App() {
const [str, setStr] = useState('')
return <>
{/* 输入导致跟新 */}
<input value={str} onChange={(e) => setStr(e.target.value)} />
<div>{str}</div>
<Counter count={0} />
</>
}
const Counter: FC<{ count: number }> = (props) => {
console.log('渲染counter');
const { count } = props
return <>
{count}
</>
}
export default App使用memo的版本:
WARNING
Object.is({},{})返回falseObject.is([],[])返回false

tsx
import { FC, memo, useState } from "react"
function App() {
const [str, setStr] = useState('')
return <>
{/* 输入导致跟新 */}
<input value={str} onChange={(e) => setStr(e.target.value)} />
<div>{str}</div>
<Counter count={0} />
</>
}
/* memo进行缓存 */
const Counter: FC<{ count: number }> = memo((props) => {
console.log('渲染counter');
const { count } = props
return <>
{count}
</>
})
export default App思考:如果传入的是一个对象或者是一个array的时候该怎么办呢?
为了最大化使用 memo 的效果,应该尽量减少 props 的变化次数。例如,如果 props 是一个对象,可以使用 useMemo 避免父组件每次都重新创建该对象: 
tsx
import { memo, useMemo, useState } from "react"
function App() {
const [str, setStr] = useState('')
/* 这里使用useMemo缓存array */
const avatars = useMemo(() => {
return Array.from({ length: 4 }, (_, index) => {
return `https://picsum.photos/50/50?random=${index}`
})
}, [])
return <>
{/* 输入导致跟新 */}
<input value={str} onChange={(e) => setStr(e.target.value)} />
<div>{str}</div>
<AvatarList avatars={avatars} />
</>
}
const AvatarList = memo((props: { avatars: Array<string> }) => {
const { avatars } = props
console.log('渲染list') /* 只有初次渲染会触发 */
return <>
{avatars.map((avatar, i) => <img src={avatar} key={i} className="w-100px h-100px rounded-full m-2" />)}
</>
})
export default AppforwardRef
forwardRef 允许组件使用 ref 将 DOM 节点暴露给父组件
tsx
import { forwardRef, useRef } from "react"
function App() {
const videoRef = useRef<HTMLVideoElement | null>(null)
const videoProps = {
src: 'https://www.w3schools.com/html/mov_bbb.mp4',
type: 'video/mp4',
width: 500
}
function handlePlay() {
videoRef.current?.play()
}
function handlePause() {
videoRef.current?.pause()
}
return <>
<div>
<button onClick={handlePlay}>play</button>
<button onClick={handlePause}>pause</button>
</div>
<MyVideoPlayer ref={videoRef} {...videoProps} />
</>
}
type IProps = {
src: string,
type: string,
width: number
}
const MyVideoPlayer = forwardRef<HTMLVideoElement, IProps>((props: IProps, ref) => {
const { src, type, width } = props
/* 向外面暴露属性
useImperativeHandle(ref, {
}, [])
*/
return <video ref={ref} width={width} controls={true}>
<source
src={src}
type={type}
/>
</video>
})Fragment (<>...</>)
<Fragment> 通常使用 <>...</> 代替,它们都允许你在不添加额外节点的情况下将子元素组合。
tsx
<>
<OneChild />
<AnotherChild />
</>WARNING
只有需要key的时候Fragment才需要完整写不然就是<>...</>代替
例如:
tsx
function DateRangePicker({list}){
return (list.map(({start,end},index)=>{
return <Fragment key={index}>
From
<DatePicker date={start} />
to
<DatePicker date={end} />
</Fragment>
}))
}StrictMode
StrictMode 帮助你在开发过程中尽早地发现组件中的常见错误。
tsx
<StrictMode>
<App />
</StrictMode>StrictMode是严格模式,在开发环境中会调用一些函数两次(仅限应为纯函数的函数)。这些函数包括:
- 组件函数体(仅限顶层逻辑,不包括事件处理程序内的代码)
- 传递给
useStateset 函数函数、useMemo或useReducer的函数 - 部分类组件的方法
Suspense
Suspense允许在子组件完成加载前展示后备方案。
WARNING
实验组件,后续会出use来包裹进行更好的使用
tsx
<Suspense fallback={<Loading />}>
<SomeComponent />
</Suspense>//todo
指南