美文网首页
react hook的基本使用大杂烩

react hook的基本使用大杂烩

作者: 虎牙工务员刘波 | 来源:发表于2021-08-12 17:26 被阅读0次

    react hook的出现标志着无状态组件的消失。

    从百草园到三味书屋,
    从class类组件杀到纯函数组件....

    主要从这几个常用hook入手:
    useState、useEffect、 useContext、useRef、 useImperativeHandle、memo、useMemo、useCallback
    分别例举应用场景。

    1、useState

    和class的state差不多。

    最简单应用:

    export default function IndexPage() {
    
      let test = 1;
      const [data, setData] = useState(0);   //直接赋值
      const [data2, setData2] = useState(() => {   //可以是一个函数返回值
        return test + 1;
      });
      
      return (
        <div>
          <Button onClick={() => setData(1)}>测试{data}</Button>
          <Button onClick={() => setData2(2)}>测试{data2}</Button>
        </div>
      );
    }
    

    如果在某些情况不受外界影响,想拿到前一次的值:

    export default function IndexPage() {
    
      let test = 1;
      const [data, setData] = useState(0);   //直接赋值
      const [data2, setData2] = useState(() => {   //可以是一个函数返回值
        return test + 1;
      });
    
      const dosome = () => {
        setData((prevState => prevState + 1));  //通过这种方式取得最新的上一次值
      };
    
      return (
        <div>
          <Button onClick={() => dosome()}>测试{data}</Button>
          <Button onClick={() => setData2(2)}>测试{data2}</Button>
        </div>
      );
    }
    

    2、useEffect

    类似 React class 的生命周期函数componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。

    做请求:

    export default function IndexPage() {
    
      const [params, setParams] = useState({ page: 1, pageSize: 10 });  
    
      useEffect(() => {
        fetch('xxx/xxx/xxx', params).then(r => console.log(r));
      }, [params]);
    
      return (
        <div>
          <Button onClick={() => setParams({ page: 2, pageSize: 10 })}>请求</Button>
        </div>
      );
    }
    

    useEffect:只能在初始渲染和DOM更新后触发
    它的第二个参数是一个数组,即依赖,每依赖变动时候,都会触发useEffect内的方法。如果数组为空,那么只会在初始渲染运行一次。
    比如当params1或者params2或者params3,任意一个改变的时候就会打印输出1:

      useEffect(() => {
        console.log(1);
      }, [params1, params2, params3]);
    

    假设有多个不同请求时候,需要写多个对应的请求依赖,对应依赖参数变化后做出请求:

    export default function IndexPage() {
    
      const [params, setParams] = useState({ page: 1, pageSize: 10 });
      const [params2, setParams2] = useState({ page: 1, pageSize: 10 });
    
      useEffect(() => {
        fetch1('xxx/xxx/xxx', params).then(r => console.log(r));
      }, [params]);
    
      useEffect(() => {
        fetch2('xxx/xxx/xxx', params2).then(r => console.log(r));
      }, [params2]);
      
      return (
        <div>
          <Button onClick={() => setParams({ page: 2, pageSize: 10 })}>请求1</Button>
          <Button onClick={() => setParams2({ page: 1, pageSize: 5 })}>请求2</Button>
        </div>
      );
    }
    

    当点击请求1,修改params参数变化,触发第一个useEffect;点击请求2,修改params2参数变化,触发第二个useEffect,发起请求以此类推。
    卸载时候,如清除定时器:

    export default function IndexPage() {
    
      const [params, setParams] = useState({ page: 1, pageSize: 10 });
    
      useEffect(() => {
        let time = setInterval(() => {
          console.log(111);
        }, 1000);
        return () => {    //这里return一个函数,表示卸载时候运行的方法
          clearInterval(time);
        };
      }, [params]);
    
      return (
        <div>
          <Button onClick={() => setParams({ page: 2, pageSize: 10 })}>请求1</Button>
        </div>
      );
    }
    

    3、useContext

    穿透传递上下文数据或者方法,在父组件创建一个上下文,再通过Provider传递给子组件,只需要包裹住,不管子组件多少层级都可以随意用到。

    -------父组件:

    import React, { useState, createContext } from 'react';
    import { Button } from 'antd';
    import Child from './Child';
    
    export const TestContext = createContext('默认参数');
    
    export default function IndexPage() {
    
      const [params, setParams] = useState('');
    
      return (
        <TestContext.Provider value={params}>
          <Button onClick={() => setParams('参数2')}>点击</Button>
          <div>父组件</div>
          <Child />
        </TestContext.Provider>
      );
    }
    

    -------子组件:这里子组件引用孙组件

    import React from 'react';
    import ChildTwo from '../ChildTwo';
    
    function Index() {
    
      return (
        <div>
          <div>
            孩子组件
          </div>
          <ChildTwo />
        </div>
      );
    }
    
    export default Index;
    

    -------孙组件:最终取值

    import React, { Component, useContext } from 'react';
    import { TestContext } from '../index';
    
    function Index() {
    
      let getContext = useContext(TestContext);
    
      return (
        <div>
          孙子组件: {getContext}
        </div>
      );
    }
    
    export default Index;
    
    点击前:
    点击后:

    4、useImperativeHandle(需要配合forwardRef、useRef)

    作用:hook中父组件可以直接调用子组件的方法

    正常下,我们编写代码,都是把父组件方法通过props传递给子组件运行,某些情况下,需要把子组件方法传递给父组件,hook组件需要这样写,父组件使用useRef并且赋给子组件:
    请注意:hooks中要使用useRef,而class组件要使用createRef。
    -----父组件

    import React, { useRef } from 'react';
    import { Button } from 'antd';
    import Child from './Child';
    
    export default function IndexPage() {
    
      const childRef = useRef();
    
      const clickChild = () => {
        childRef.current.change();
      };
    
      return (
        <div>
          <Button onClick={() => clickChild()}>点击</Button>
          <div>父组件</div>
          <Child ref={childRef} />
        </div>
      );
    }
    

    ------子组件
    useImperativeHandle的第一个参数接收到的ref,第二个是一个函数,函数需要返回传递给父组件的方法,子组件用forwardRef包裹,类似高阶函数用法。

    import React, { useImperativeHandle, useState, forwardRef } from 'react';
    
    function Index(props, ref) {
    
      const [data, setData] = useState(1);
    
      const test = () => {
        setData(data + 1);
      };
    
      useImperativeHandle(ref, () => ({    
        change: () => test(),
      }));
    
      return (
        <div>
          <div>
            孩子组件:{data}
          </div>
        </div>
      );
    }
    
    export default forwardRef(Index);
    

    每次点击按钮数值加1


    5、memo

    效果等同与class组件的PureComponent,或者是shouldCompomentUpdate,只能进行浅层比较,既简单数据类型如:bool、string、number、undefind、null
    作用:避免组件做不必要的更新(减少频繁更新次数)

    使用非常简单,用包裹于子组件。一般情况下也是用来控制,当父组件传给子组件的值变化时候,子组件避免做不必要频繁更新次数。

    import React, { memo } from 'react';
    
    function Index() {
    
      return (
        <div>
    
        </div>
      );
    }
    
    export default memo(Index);
    

    应用场景:
    https://www.jianshu.com/p/822e061d960f

    相关文章

      网友评论

          本文标题:react hook的基本使用大杂烩

          本文链接:https://www.haomeiwen.com/subject/iyflbltx.html