【React】函数组件hooks

函数式组件

rfc

  • 函数式组件的this为undefined ,因为babel开启了严格模式
  • render执行:解析组件标签,发现是函数定义,随后调用该函数,将虚拟DOM转为真实DOM
  • 函数就相当于render,会调用n+1
  • 再没有hooks之前,函数只能通过首个参数接收props,state,生命周期,ref都不行

useState(state状态)

声明

  • 采用数组解构,第一个为state属性,第二个为更改state的方法(setState)

    let [num, setNum] = useState(0)
    

使用

同样有两种写法,但多次调用最后都会合并

  • 对象式

    setNum(num + 1)
    
  • 函数式:参数为当前state

    setNum((num) => num + 1)
    
  • useState()参数为初始值,并会作为缓存,所以不会随着 render 而调用

useEffect(生命周期)

useEffect(callback,[])//监听更新的名单
  • 参数:

    • 如果没值,则为初始化+监听所有,callback相当于 componentDidMount + componentDidUpdate
    • 如果为[],则为初始化,callback相当于componentDidMount
    • 如果[]里有值,则为初始化+监听指定值的更新
  • 模拟componentWillUnmount:callback内再 return 一个 callback

    useEffect(() => {
            let timer = setInterval(() => {
                setNum(num+1)
            }, 500);
            return () => {
                clearInterval(timer)
            }
        }, [num])
    

useRef

  • 和类组件createRef用法相似
import React, {useRef } from 'react'
export default () => {
    let input1=useRef()
    let show=()=>{
        console.log(input1.current.value);
    }
    return (
        <>
            <input ref={input1} onChange={show} type="text" />
        </>
    )
} 

Fragment

  • Fragment不会被渲染(类似vue的template)

    //简写
    <> </>
    
  • Fragment只能接受key,并不能简写

    <Fragment key={}>
    </Fragment>
    

useReducer

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 参数触发机制同useEffect
  • 返回的值不受响应式影响
  • 返回callback返回的值,并优先读取缓存
  • 使用场景:函数式组件没有getSnapshotBeforeUpdate生命周期钩子,存在性能问题(同类组件的React.Component性能问题)
export default function WithoutMemo() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    function expensive() {
        let sum = 0;
        for (let i = 0; i < count * 100; i++) {
            sum += i;
        }
        return sum;
    }
 
    return <div>
        <h4>{count}-{val}-{expensive()}</h4>
        //无论是修改count还是val,都会触发expensive的执行
        <div>
            <button onClick={() => setCount(count + 1)}>+c1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;

//使用useMomo
export default function WithMemo() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
    const expensive = useMemo(() => {
        console.log('compute');
        let sum = 0;
        for (let i = 0; i < count * 100; i++) {
            sum += i;
        }
        return sum;
    }, [count]);
 
    return <div>
        <h4>{count}-{expensive}</h4>
        {val}
        <div>
            <button onClick={() => setCount(count + 1)}>+c1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

useCallback

  • 和useMemo类似,只不过其返回的是优先缓存的函数
  • 使用场景:父子组件的性能优化
import React, { useState, useCallback, useEffect } from 'react';
function Parent() {
    const [count, setCount] = useState(1);
    const [val, setVal] = useState('');
 
    const callback = useCallback(() => {
        return count;
    }, [count]);
    return <div>
        <h4>{count}</h4>
        <Child callback={callback}/>
        <div>
            <button onClick={() => setCount(count + 1)}>+</button>
            <input value={val} onChange={event => setVal(event.target.value)}/>
        </div>
    </div>;
}
 
function Child({ callback }) {
    const [count, setCount] = useState(() => callback());
    useEffect(() => {
        setCount(callback());
    }, [callback]);
    return <div>
        {count}
    </div>
}

useImperativeHandle

useLayoutEffect

useDebugValue

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值