hook

1.Sass的镜像配置

yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g

2. useState(状态)

//useState返回个数组,第一个参数是state的值,第二个参数是改变state值的函数
//useState本身就是一个函数,函数接收值是state的初始值

function Example() {
  const [show, setShow] = useState(true);
  const [count, setCount] = useState(0);

  return (
    <div>
      {show && <h3>标题的显示和隐藏</h3>}
      <Button onClick={(e) => setShow(!show)}>显示/隐藏</Button>
      <Count name="张三" count={count} changeCount={changeCount}></Count>
    </div>
  );
}

function Counter(props) {
  const { count, name, changeCount } = props;
  return (
    <div>
      <h3>
        {name}开始计数:{count}
      </h3>
      <Button onClick={(e) => changeCount()}>计数</Button>
    </div>
  );
}

3.useEffect (副作用)

import React, { useEffect, useState } from "react";

function Test() {
  const [count, setCount] = useState(0);

  // 第一个参数是个函数,表示是副作用要执行的操作
  useEffect(() => {
    console.log("组件的mount和更新");
  });

  // 第二个参数是执行第一个参数函数的依赖,当依赖变化时会进行更新执行
  // 下面数组是空,所以只有加载的第一次才会执行,后面就不会执行了
  // 类似 componentDidMount
  useEffect(() => {
    console.log("组件的mount");
  }, []);

  // 当有依赖时,依赖更新就会执行函数,包括返回的函数
  // 而且useEffect是可以多个同时使用的,顺序从上到下
  useEffect(() => {
    console.log("组件的mount和更新2");
    return () => {
      console.log("返回的函数");
    };
  }, [count]);

  // 第一个参数函数,返回值如果是一个函数,表示的是componentWillUnmount,组件卸载
  // 组件卸载的操作可以在返回的函数里面进行操作
  // 此时没有依赖,只会执行一次,就是组件第一次加载
  useEffect(() => {
    console.log("组件的mount");
    return () => {
      console.log("componentWillUnmount 组件卸载");
    };
  }, []);

  return (
    <>
      <p>{count}</p>
      <button onClick={(e) => setCount(count + 1)}>改变count的值</button>
    </>
  );
}

export default Test;

4.useRef(获取ref实例)

// ref的使用
function RefDom() {
  const ref = useRef(); //创建ref
  const valRef = useRef(0); // 记录值(上一次的值)
  const [count, setCount] = useState(0);

  useEffect(() => {
    ref.current.value = "ref的测试"; //操作dom
  }, []);

  // useEffect是在render结束后进行执行
  useEffect(() => {
    valRef.current = count; //此时只是更新了valRef.current的数值,组件不会触发render
  }, [count]);

  return (
    <div>
       {/*ref记录值的使用*/}
      <p>ref的记录上次的值:{valRef.current}</p>
      <p>最新的值: {count}</p>
      <Button type="primary" onClick={(e) => setCount(count + 1)}>
        计数
      </Button>
      <br /> <br />
      {/*赋值ref到dom*/}
      <input ref={ref} />
    </div>
  );
}

5.useCallback,memo, useMemo的使用

memo

就是类似PureComponent,只不过memo针对的是函数式组件,进行浅比较,对性能进行优化

useMemo

一般是对高计算的操作进行优化,返回一个记忆的值, 仅会在某个依赖项改变时才重新计算记忆的值

useCallback

和useMemo差不多,只不过返回一个记忆的回调函数,是useMemo的特殊版
// 此组件除了接收属性,还接收了函数
// 如果父组件因为除了count其他的元素进行重新render,重新定义了changeCount函数,那么就不能起到性能优化的作用了
// memo就毫无意义了,所以要对changeCount进行记忆,只有count改变时候在进行重新定义

const Count = memo((props) => {
  console.log("counter的渲染");
  const { count, name, changeCount } = props;
  return (
    <div>
      <h3>
        {name}开始计数:{count}
      </h3>
      <Button onClick={(e) => changeCount()}>计数</Button>
    </div>
  );
});
function Example() {
  console.log("父元素的渲染");
  const [show, setShow] = useState(true);
  const [count, setCount] = useState(0);

  // 对changeCount进行记忆,只有count变化,才对函数进行执行
  // show的变化不会引起函数的执行,也不会改变changeCount,导致Count组件的memo不生效
  const changeCount = useCallback(() => {
    console.log("父计数渲染");
    setCount(count + 1);
  }, [count]);

  // 对复杂的运算进行记忆,不用频繁执行,返回个值
  // 这里只是举个例子
  const total = useMemo(() => {
    console.log("计算");
    let t = 0;
    for (let i = 0; i <= count; i++) {
      t += i;
    }
    return t;
  }, [count]);

  return (
    <div>
      {show && <h3>标题的显示和隐藏</h3>}
      <Button onClick={(e) => setShow(!show)}>显示/隐藏</Button>
      <hr />

      <h3>总数的和:{total}</h3>
      <Count name="张三" count={count} changeCount={changeCount}></Count>
    </div>
  );
}

6. 自定义hook(有点mixin的意思,通过hook对组件进行混入)

函数名字要以use开头,这是约定,这样才能使用基础hook,比如useState之类的
import { useEffect, useState, useCallback } from "react";

//这是一个记录滚动位置的自定义hook

export const useScroll = () => {
  const [pos, setPos] = useState(0);

  // 记忆记录位置的操作,第一次加载的时候定义下
  const getScrollPos = useCallback(() => {
    setPos(window.scrollY); //改变位置,触发render
  },[]);

  // getScrollPos改变时候,才会重新定义事件
  // getScrollPos被记忆了,所以不会改变,事件就只会被定义一次
  useEffect(() => {
    document.addEventListener("scroll", getScrollPos);

    return () => {
      document.removeEventListener("scroll", getScrollPos);
    };
  }, [getScrollPos]);

  return pos; //如果只有一个值,可以直接返回,如果多个可以用[]的方式
};
// 使用方式

import { useScroll } from "./hk";

function DefineHook() {
  const pos = useScroll();
  return <h4>当前的滚动位置是:{pos} px</h4>;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值