使用object.is来比较每个依赖项和它先前的值
依赖项为空数组的effect不会在组件任何props和state发生改变时重新运行
当useEffect依赖于外部传入props对象时,容易造成死循环
需要对依赖对象进行深比较
import { isEqual } from 'lodash'
const useCompare = (value: any, compare: any) => {
const ref = useRef(null)
if(!compare(value,ref.current)){
ref.current = value
}
return ref.current
}
const params = useCompare({
...accessParam,
...reqParam,
},isEqual)
useEffect(()=>{
},[params])
应用一个不需要渲染的值,改变ref不会触发重新渲染
const ref = useRef(value)
不要在渲染期间写入或读取ref.current
通过ref操作DOM:
const ref = useRef(null)
<input ref={ref} />
获取子元素的ref
const children = forwardRef((props,ref)=>{
return (
<Input ref={ref}/>
)
})
跨层级传递变量
const ThemeContext = createContext(null)
<ThemeContext.Provider value='dark'>
<Form>
<ThemeContext.Provider/>
//使用context
const context = useContext(ThemeContext)
通过context更新对象
<Provider value={{user,setUser}}></Provider>
用于定义ref暴露出的句柄
允许向组件里面添加一个reducer用于状态管理
(state,action) => newState
用于更新state的纯函数返回值为数组:[currentState, dispatch]
注意:dispatch函数为下一次渲染更新state,因此调用后拿不到更新后的值。如果提供state与当前state一致,react会跳过组件和子组件的重新渲染
用法:
//state是只读的,不可尝试修改
const reducer = (state,action) => {
if(action.type === '') {
return {
...state
}
}
}
const [state, dispatch] = useReducer(reducer, { age: 42 })
//调用更新函数
dispatch({type: ''})
允许组件在props没有改变的情况下跳过重新渲染
如果传递给组件的props是一个对象,应使用useMemo避免父组件每次重新创建该对象
如果传递给组件的props是一个函数,应使用useCallback进行缓存
允许将JSX作为children渲染至DOM不同部分
应用场景:当样式有overflow:hidden或z-index,需要子组件能视觉上跳出当前容器
import {createPortal} from 'react-dom'
<div>
{
createPortal(<p />, document.body)
}
</div>