React常用的Hooks

useState

  1. // 使用
  2. const [n,setN] = React.useState(0)
  3. const [user,setUser] = React.useState({name : 'x',age : x})
  4. const onClick = () =>{
  5. setUser({
  6. ...user, // 无法进行局部更新,需要配合 ...进行拷贝
  7. name : 'y'
  8. })
  9. }
  10. const [state , setState] = React.useState(()=>{return initialState})
  11. // 返回初始的state 只能执行一次
  12. const onClick = () =>{
  13. setN(n+1)
  14. setN(n+1) // 无法加2
  15. setN(i => i+1)
  16. setN(n => i+1) // 可以加2
  17. }

在React中 setUser(obj)如果obj 的地址没变,那么React就认为数据没有变化,需要生成一个新的对象

useReducer

四步: 1、创建初始值 initialState
2、创建所有操作reducer(state,action)
3、传给useReducer 得到读和写的API
4、调用写的({type:’操作类型’})

  1. const initial = { n : 0 }
  2. // 主要流程
  3. const reducer = (state , action) =>{
  4. if(action.type === 'add'){
  5. return { n : state.n + action.number }
  6. }else {
  7. throw new Error('unknown')
  8. }
  9. }
  10. function App(){
  11. const [state , dispatch] = React.useReducer(reducer , initial)
  12. const n = state.n // const {n} = state
  13. const onClick = () =>{
  14. dispatch({type : 'add' , number : 1})
  15. return(
  16. <div className="App">
  17. <h1>n: {n}</h1>
  18. <button onClick={onClick}>+1</button>
  19. </div>
  20. )
  21. }

useContext

  1. // 创建上下文
  2. const n = React.createContext(null)
  3. // 圈定作用域
  4. function App(){
  5. const [n,setN] = useState(0)
  6. return(
  7. <n.Provider value={{ n, setN }}>
  8. <div className="App">
  9. <X />
  10. </div>
  11. </n.Provider>
  12. )
  13. }
  14. // 使用上下文
  15. function X() {
  16. const { n, setN } = useContext(n);
  17. return (
  18. <div>
  19. n: {n}
  20. </div>
  21. );
  22. }

useEffect 和 useLayoutEffect

useEffect在浏览器渲染结束后执行,useLayoutEffect在浏览器渲染前执行。虽然useLayoutEffect先执行,但是为了用户体验优先使用useEffect

  1. useEffect(()=>{
  2. console.log("useEffect")
  3. },[]) // 首次渲染
  4. useEffect(()=>{
  5. console.log("useEffect")
  6. },[x]) // 当x发生变化进行渲染
  7. useLayoutEffect(()=>{
  8. console.log("useLayoutEffect")
  9. }) // 所有的都进行渲染

useMemo 和 useCallback

useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;并且这两个hooks都返回缓存的值,useMemo返回缓存的变量useCallback返回缓存的函数

  1. // 使用React.memo
  2. function Child(props){
  3. console.log("hello")
  4. return(
  5. <div>props.data</div>
  6. )
  7. }
  8. const Child2 = React.memo(Child)
  9. // 使用useMemo,只有在m发生变化才会使用新的
  10. const onClickChild = useMemo(()=>{
  11. return () =>{
  12. console.log(m)
  13. }
  14. },[m])
  15. // 当返回函数时
  16. useMemo(()=> (x)=>consloe.log(x),[m])
  17. // 上下等价
  18. useCallback((x) => consloe.log(x),[m])

useRef

useRef返回一个可变的ref对象,其.current属性初始化为传入的参数
在组件不断render的时候保持不变,当变化时不会自动render,需要自行调用

  1. const count = useRef(0) // 初始化
  2. // current 为了保证对象不变
  3. useEffect(() =>{
  4. count.current += 1
  5. consloe.log(count.current)
  6. })

forwardRef

当一个函数组件需要接受其他组件传来的ref参数,必须要用forwardRef。可以接受一个ref参数

  1. const x = React.forwardRef((props,ref) =>{})

useImperativeHandle

useImperativeHandle让在使用ref时自定义暴露给父组件的实例指。

  1. useImperativeHandle(ref,()=>({
  2. x : ()=>{} // x为暴露给父组件的方法
  3. }))

自定义Hook

一般使用useXXX 开头