react:React Hook函数

使用规则

只能在组件中或者其他自定义的Hook函数中调用

只能在组件的顶层调用,不能嵌套在iffor、 其他函数中

基础Hook 函数

useState

useState是一个hook函数,它允许我们向组件中添加一个状态变量,从而控制影响组件的渲染结果

示例1

java 复制代码
function App() {

  // 创建一个状态变量
  // count: 状态变量,setCount: 更新状态变量的函数
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>当前数值是:{count}</p>
      <button onClick={() => setCount(count + 1)}>加一</button>
    </div>
  )
}

示例2

java 复制代码
function App() {
  const [userName, setUserName] = useState("111");

  return (
    <div>
      <input
        type="text"
        value={userName}
        placeholder="请输入"
        onChange={(e) => setUserName(e.target.value)}
      />
      <div>当前输入值是:{userName}</div>
    </div>
  );
}

注意:

  • react中,状态被认为是只读的,直接修改状态不能引发视图的更新
  • 对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改
java 复制代码
function App() {
  const [form, setForm] = useState({
    age: 0
  })

  return (
    <div>
      <p>当前年龄是:{form.age}</p>
      <button onClick={() => setForm({
        ...form,
        age: form.age + 1
      })}>加一</button>
    </div>
  )
}

useRef

获取、操作DOM

java 复制代码
function App() {
  // 使用 useRef生成ref对象,并绑定到dom上
  const inputRef = useRef(null);

  // 获取dom
  const getDom = () => {
    console.log(inputRef.current);
  };

  return (
    <div>
      <input type="text" ref={inputRef} placeholder="请输入" />
      <button onClick={getDom}>获取dom</button>
    </div>
  );
}

useEffect

useEffect是一个React Hook函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAX请求、更改DOM

java 复制代码
function App() {
  const [content, setContent] = useState("");
  const [note, setNote] = useState("");
  useEffect(() => {
    // 获取每日英语
    function getEnglish() {
      fetch("https://api.oioweb.cn/api/common/OneDayEnglish")
        .then((res) => res.json())
        .then((data) => {
          console.log(data);
          setContent(data.result.content);
          setNote(data.result.note);
        });
    }

    getEnglish();
  }, []);
  return (
    <div>
      <div>英文:{content}</div>
      <div>翻译:{note}</div>
    </div>
  );
}

不同依赖项说明

  • 没有依赖项,组件初始渲染+组件更新时执行
  • 空数组依赖,只在初始渲染时执行一次
  • 添加特定依赖项,组件初始渲染+特性依赖项变化时执行

没有依赖项

java 复制代码
function App() {
  const [content, setContent] = useState(0);
  useEffect(() => {
    console.log("副作用执行了");
  });
  return (
    <div>
      <button onClick={() => setContent(content + 1)}>{content}</button>
    </div>
  );
}

空数组依赖

java 复制代码
function App() {
  const [content, setContent] = useState(0);
  useEffect(() => {
    console.log("副作用执行了");
  }, []);
  return (
    <div>
      <button onClick={() => setContent(content + 1)}>{content}</button>
    </div>
  );
}

特性依赖变化

java 复制代码
function App() {
  const [content, setContent] = useState(0);
  useEffect(() => {
    console.log("副作用执行了");
  }, [content]);
  return (
    <div>
      <button onClick={() => setContent(content + 1)}>{content}</button>
    </div>
  );
}

清除副作用

useEffect中编写的由渲染本身引起的对接组件外部的操作 , 社区也叫做副作用操作,比如在useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清除副作用。

java 复制代码
useEffect(() => {
  console.log("副作用执行了");
  return () => {
    console.log("清除副作用");
  };
}, []);

清除副作用的函数最常见的执行时机是在组件卸载时自动执行。

java 复制代码
function App() {
  const [show, setShow] = useState(true);
  return (
    <div>
      父组件
      <button onClick={() => setShow(false)}>卸载Son组件</button>
      {show && <Son />}
    </div>
  );
}
function Son() {
  const [currentDate, setCurrentDate] = useState("");

  useEffect(() => {
    const timer = setInterval(() => {
      const newDate = new Date().toLocaleTimeString();
      setCurrentDate(newDate);
      console.log("当前时间:", newDate);
    }, 1000);

    return () => {
      // 不清除副作用,即使组件不适用了,定时器还会执行
      clearInterval(timer);
    };
  }, []);

  return (
    <div>
      <div>子组件</div>
      <div>当前时间是:{currentDate}</div>
    </div>
  );
}

自定义Hook

自定义Hook是以use打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用

java 复制代码
function App() {

  const [state, toggle] = useToggle()

  return (
    <div>
      { state && <div>这是一个div</div> }
      <button onClick={toggle}>切换</button>
    </div>
  )
}

function useToggle(){
  // 可复用的逻辑代码
  const [state, setState] = useState(true)

  const toggle = () => {
    setState(!state)
  }

  // 那些状态和方法需要在其他组件中使用,则返回
  return [state, toggle]
}

通用思路

  • 声明一个以use大头的函数
  • 在函数体内封装可以复用的逻辑
  • 将组件中用的的状态或者回调函数return出去(对象或者数组形式)
  • 在那个组件中用到这个逻辑,就执行这个函数,结构出来状态和回调进行使用
java 复制代码
function App() {

  const [content, note] = useOneDayEnglish();

  return (
    <div>
      <div>英文:{content}</div>
      <div>翻译:{note}</div>
    </div>
  );
}


function useOneDayEnglish() {
  const [content, setContent] = useState("");
  const [note, setNote] = useState("");
  useEffect(() => {
    // 获取每日英语
    function getEnglish() {
      fetch("https://api.oioweb.cn/api/common/OneDayEnglish")
        .then((res) => res.json())
        .then((data) => {
          console.log(data);
          setContent(data.result.content);
          setNote(data.result.note);
        });
    }

    getEnglish();
  }, []);

  return [content, note];
}
相关推荐
沉默璇年6 小时前
react中useMemo的使用场景
前端·react.js·前端框架
红绿鲤鱼7 小时前
React-自定义Hook与逻辑共享
前端·react.js·前端框架
loey_ln9 小时前
FIber + webWorker
javascript·react.js
zhenryx10 小时前
前端-react(class组件和Hooks)
前端·react.js·前端框架
老码沉思录14 小时前
React Native 全栈开发实战班 - 性能与调试之打包与发布
javascript·react native·react.js
沉默璇年18 小时前
react中Fragment的使用场景
前端·react.js·前端框架
GISer_Jing19 小时前
React渲染流程与更新diff算法
前端·javascript·react.js
老码沉思录1 天前
React Native 全栈开发实战班 - 性能与调试之内存管理
javascript·react native·react.js
yqcoder1 天前
reactflow 中 reactflowprovider 组件作用
前端·javascript·react.js
前端郭德纲1 天前
ReactNative的环境搭建
javascript·react native·react.js