React常用Hooks及自定义Hooks

122 阅读2分钟

1.useState

语法:
const [xxx,setXxx] = useState<'变量的类型'>('默认值';
const [data,setData] = useState<'string'>('123');
是否异步:
1. 在正常的react的事件流里(如onClick等)是异步的(不会立即更新SetState的执行结果);
    多次执行setState和useState只会重新render一次;
    setState会进行state的合并 useState不会;
    
2.setTimeoutPromise.then等异步事件中(或绑定原生事件)是同步的

2.useEffect

语法
useEffect((console.log('执行相关代码')) => {a,b,...n})
useEffect(() => {
    console.log('123')
    return () => {
        console.log('xxx')
    }
},[])
监听后边的参数变化,a-n如果有变化则执行第一个参数中的的代码块;
若没有第二个参数,则只在页面第一次render的时候执行一次
return中的代码在页面被销毁时执行(面试被问过,焯)

3.useCallBack

语法:
const xxx = useCallback(() => {
    setData(data + 1);
}, [data]);
作用:
usecallBack返回一个函数,主要作用是减少子组件不必要的渲染。(面试还问就回答`useCallback` 的真正目的还是在于缓存了每次渲染时 inline callback 的实例,这样方便配合上子组件的 shouldComponentUpdate 或 React.memo 起到减少不必要的渲染的作用。需要不断提醒自己注意的是,在大部分 callback 都会是 inline callback 的未来,React.memoReact.useCallback 一定记得需要配对使用,缺了一个都可能导致性能不升反“降”,毕竟无意义的浅比较也是要消耗那么一点点点的性能,再问装死。)
// father
import { Button } from "antd";
import React, { useCallback, useState } from "react";
import ButtonTest from './components/Button'
function Test() {
    const [count1, setCount1] = useState(0);
    const [count2, setCount2] = useState(0);
    const [count3, setCount3] = useState(0);

    const handleClickButton1 = () => {
        setCount1(count1 + 1);
    };

    const handleClickButton2 = useCallback(() => {
        setCount2(count2 + 1);
    }, [count2]);


    return (

        <div>
            <div>
                <ButtonTest onClickButton={handleClickButton1}>Button1</ButtonTest>
            </div>
            <div>
                <ButtonTest onClickButton={handleClickButton2}>Button2</ButtonTest>
            </div>
            <div>
                <ButtonTest
                    onClickButton={() => {
                        setCount3(count3 + 1);
                    }}
                >
                    Button3
                </ButtonTest>
            </div>

        </div>
    )
    }
    export default Test
 // child 
 import { Button } from "antd";
import React, { useCallback, useState } from "react";

const ButtonTest =(props:any) => {
 const {onClickButton,children} =props
    return (
        <div>
         <>
        <button style={{background:'#000',margin:'10px'}} onClick={onClickButton}>{children}</button>
            <span>{Math.random()}</span>
         </>
        </div>
    )
}
export default React.memo(ButtonTest)
//  这里或许会注意到 Button 组件的 React.memo 这个方法,此方法内会对 props 做一个浅层比较,如果如果 props 没有发生改变,则不会重新渲染此组件。

点击Button1 13会变化
点击Button2 123都会变化
点击Button3 13会变化
原因:因为useCallBack的依赖项是count2,useCallBack会根据count2是否发生变化来决定是否返回内部的函数,由于我们的这个方法只依赖了 `count2` 这个变量,而且 `count2` **只在**点击 Button2 后才会更新 `handleClickButton2`,所以就导致了我们点击 Button1 不重新渲染 Button2 的内容。

... 明天写useRef useMemo useHistory useParams