useHooks

作者: RadishHuang | 来源:发表于2021-11-03 15:25 被阅读0次
import React, { useState, useEffect, useRef } from "react";

/**
 * react运行机制:
 * useState和useEffect,都是在页面render的时候生成了本次render的state,function,effects
 * 所以页面每次有更新,都会执行effect方法
 * 如果后面跟的是一个空数组,只会在第一次执行的时候调用。这样以后render的时候,都不会生成新的effects
 * 这样可能会导致,拿到的state不是最新的state
 * 如果要拿到最新的state,可以在数组后面监听某个值的变化,从而再去做effect的事情,保证这次的render是
 * state的更新,拿到最新的一份state的数据。
 * */ 


/**
 * useRef
 * 1、保存全局的一个状态,这样就不会导致状态的一个丢失,拿到的永远是最新一次render的状态。
 * 2、可以获取到dom的节点,调用方法。
 * **/

const LikeButton: React.FC = () => {
  const [count, setCount] = useState(0);
  const [on, setOn] = useState(false);
  const [pos, setPos] = useState({ x: 0, y: 0 });

  const countRef = useRef(0);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {  // 不传参的情况下,每次页面有更新都会执行一次
    document.title = `tap ${count} num`;
  }, [count])

  useEffect(() => { // react 在执行这次effect的时候,会把上次的effect清除
    console.log(' addEventListener')
    const changePos = (e: MouseEvent) => {
      setPos({ x: e.clientX, y: e.clientY })
    }
    // console.log(' addEventListener', pos);
    document.addEventListener('click', changePos);
    return () => {
      // 会在下一次执行上面 addEventListener 方法的时候,回调这个removeEventListener
      // 先把上次的状态清除
      // console.log(' removeEventListener', pos);
      document.removeEventListener('click', changePos);
    }
  }, []);

  return (
    <>
      <div onClick={() => { 
        setCount(count + 1); 
        countRef.current = (count + 1);

        if (inputRef.current) {
          inputRef.current.focus();
        }
        
      }}>相加<span>{count}</span></div>

      <div onClick={() => {
        console.log(' == 延迟3秒获取state , 点击这个按钮,然后狂点相加的时候,alert弹出的count只会是点击按钮那一刻的count ==');
        setTimeout(()=>{
          alert(count);
          console.log(' === ref ==', countRef.current);
        }, 3000)
      }}>延迟3秒去获取状态的具体值</div>

      <div onClick={() => { setOn(!on) }}>{on ? 'on' : 'off'}</div>

      <div>posX{pos.x} === posY{pos.y}</div>
      <input ref={inputRef} />
    </>
  )
}

export default LikeButton;

自定义hooks

import { useEffect, useState } from "react";

/**
 * 自定义hooks
 * 但是这些hooks都是相互隔离的,A页面的pos和B页面的pos的数据是指向的不同内存
 * 虽然显示的数据是一样的,但是实际的内存指向都是不一样的
 * */ 

const useMousePostion = () => {
  const [pos, setPost] = useState({ x: 0, y: 0 });

  useEffect(()=>{
    const handleMove = (e: MouseEvent) => {
      setPost({ x: e.clientX, y: e.clientY });
    }
    document.addEventListener('mousemove', handleMove);
    return () => {
      document.removeEventListener('mousemove', handleMove);
    }
  }, [])
  return pos;
}

export default useMousePostion;




  const pos = useMousePostion();

相关文章

网友评论

      本文标题:useHooks

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