一、useState + useReducer
const ReactModel = ()=>{
const [n,setN] = useState(1)
const onClick = ()=>{
setN(n+1)
}
return <div onClick={onClick}>{n}</div>
}
const reducer = (state,action)=>{
switch (action.type){
case 'setN':{
return {
...state,
n: action.n
}
}
}
}
const ReactModel = ()=>{
const [state,dispatch] = useReducer(reducer,initialState)
const onClick = ()=>{
dispatch({type:'setN',n:state.n+1})
}
return <div onClick={onClick}>{n}</div>
}
二、useEffect + useLayoutEffect
const ReactModel = ()=>{
useEffect(()=>{
console.log(1)
return ()=>{
console.log(2)
}
})
}
const ReactModel = ()=>{
useEffectLayout(()=>{
console.log(1)
return ()=>{
console.log(2)
}
})
}
三、memo + useMemo/useCallback
const ReactModel = ()=>{
const [n,setN] = useState(1)
const onClick = useMemo(()=>{
return ()=>{
console.log(n)
}
},[n])
return <ReactModel2 onClick={onClick} n={n} />
}
const ReactModel2 = React.memo((props)=>{
return <div onClick={props.onClick}>{props.n}</div>
})
const ReactModel = ()=>{
const [n,setN] = useState(1)
const onClick = useCallback(()=>{
console.log(n)
},[n])
return <div onClick={onClick}>{n}</div>
}
四、useRef、forwardRef、useImperativeHandle
const ReactModel = ()=>{
const nRef = useRef(1)
const onClick = ()=>{
console.log(nRef.current)
nRef.current++
}
return <div onClick={onClick}>按钮<div>
}
const ReactModel = ()=>{
const buttonRef = useRef(null)
return <Button ref={button}>按钮</Button>
}
const Button = React.forwardRef((props,ref)=>{
return <button ref={ref} {...props}>
})
const Button = React.forwardRef((props,ref)=>{
const realButton = createRef(null)
useImperativeHandle(ref,()=>({
x: ()=>{
realButton.current.remove()
}
}))
})
// 应该叫 setRef
useRef
- 目的
- 如果你需要一个值,在组件不断 render 时保持不变
- 初始化:const count = useRef(0)
- 读取:count.current
- 为什么需要 current?
- 为了保证两次 useRef 是同一个值
- 延伸
- 看看 Vue3 的 ref
- 初始化 const count = ref(0)
- 读取 count.value
- 不同点:当 count.value 变化时,Vue3 会自动 render
五、自定义 Hooks
封装自定义操作
const useList = ()=>{
const [list,setList] = useState(null)
useEffect(()=>{
ajax('/list').then(list=>{
setList(list)
})
},[])
return {
list,
setList
}
}
「@浪里淘沙的小法师」