React中常用的钩子

在当今,React的钩子写法已经逐渐成为了一种主流开发模式,本文将介绍几种在React中常用的钩子

  1. useState
    可以用来双向绑定,创建需要监听变化并且使用的数据
    使用该钩子定义时,参数可以是一个直接定义好的变量,也可以是一个函数,函数返回什么,初始状态就是什么,函数只会被调用一次,用在初始值是动态值的情况下(props)
javascript 复制代码
import React, { useState } from 'react';

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

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Counter;
  1. useRef
    用于获取操作DOM
    可以存储上一次渲染的值,用useRef创建一个对象来存储setState前的旧值
javascript 复制代码
import { useRef } from "react";

/**
 * 1、useRef生成ref对象 绑定到dom标签上
 * 2、DOM可用时,ref.current获取DOM,渲染完毕之后DOM生成之后才可用
 */
function App() {
  const inputRef = useRef(null);
  const showDom = () => {
    console.log(inputRef.current);
  };
  return (
    <div className="App">
      <input type="text" ref={inputRef} />
      <button onClick={showDom}>获取DOM</button>
    </div>
  );
}

也可以用于保存数据,特点是跨组件周期,组件重新渲染的时候还会存在,确保不会丢失

javascript 复制代码
import React, { useRef, useEffect, useState } from 'react'

export default function ref() {
    const [count, setCount] = useState(0)
    const timerId = useRef()
    useEffect(() => {
        timerId.current = setInterval(() => {
            setCount(count => count + 1)
        }, 1000)
    }, [])
    const stopCount = () => {
        console.log(timerId);
        clearInterval(timerId.current)
    }
    return (
        <div>
            {count}
            <button onClick={stopCount}>停止</button>
        </div>
    )
}
  • useEffect
    这个钩子在我们开发的时候特比较常用,所对应的情况也比较多一点,可以看作类组件挂载完成之后、组件数据更新完成之后、组件卸载之前去执行,主要分为以下几种情况
  • 没有依赖项
javascript 复制代码
function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log(111);
  });
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>+{count}</button>
    </div>
  );
}
  • 空数组依赖
javascript 复制代码
const URL = "http://geek.itheima.net/v1_0/channels";
function App() {
  const [list, setList] = useState([]);
  useEffect(() => {
    // 额外的操作,获取频道列表
    async function getList() {
      const res = await fetch(URL);
      const list = await res.json();
      console.log(list);
      setList(list.data.channels);
    }
    getList();
  }, []);
  return (
    <div>
      this is app
      {list.map((i) => (
      <li key={i.id}>{i.name}</li>
    ))}
    </div>
  );
}
  • 添加特定的依赖项
javascript 复制代码
function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(111);
  },[count]);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>+{count}</button>
    </div>
  );
}

最后,我们在使用完成后,还应该清除对应的副作用,最常见的时机是在组件卸载时自动执行

javascript 复制代码
function Son() {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log("定时器执行中...");
    }, 1000);

    return () => {
      clearInterval(timer);
    };
  }, []);
  return <div>this is son</div>;
}

function App() {
  const [show, setShow] = useState(true);
  return (
    <div>
      {show && <Son></Son>}
      <button onClick={() => setShow(false)}>卸载Son组件</button>
    </div>
  );
}
  1. useMemo
    该钩子属于React性能优化中的一环,可以对数据进行缓存
    类似于Vue中的计算属性,可以监听某个值的变化,根据变化值重新计算新值
    会缓存计算结果,如果检测到值没有变化,即时组件重新渲染,也不会重新计算,可以有助于避免在每个渲染上浪费计算
javascript 复制代码
import React, { useMemo } from 'react';

function ExpensiveCalculation({ num }) {
  const calculateFactorial = (n) => {
    console.log('Calculating factorial...');
    return n <= 1 ? 1 : n * calculateFactorial(n - 1);
  };

  const factorial = useMemo(() => calculateFactorial(num), [num]);

  return (
    <div>
      <h2>Factorial of {num}: {factorial}</h2>
    </div>
  );
}
  1. useCallback
    用来缓存函数,使组件渲染的时候得到相同的函数实例,避免函数在组件重新渲染时重新创建
javascript 复制代码
import React, { useState, useCallback } from 'react';

function Child({ onClick }) {
  console.log('Child component rendered');
  return <button onClick={onClick}>Click Me</button>;
}

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

  // 使用 useCallback 避免函数在每次渲染时重新创建
  const handleClick = useCallback(() => {
    alert('Button clicked!');
  }, []);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <Child onClick={handleClick} />
    </div>
  );
}
  1. useReducer
    让函数组件保存状态的方式,与usestate钩子相比,结合了usestate和redux的优点,比如说在父组件想要修改子组件数据的时候,就不需要传递方法了,可以直接吧dispatch传递过去进行修改使用(通过props进行传递即可)
javascript 复制代码
import { useReducer } from 'react'

function App() {
  const reducer = (state, action) => {
    switch (action.type) {
      case 'plus':
        return state + 1;
      case 'des':
        return state - 1;
      default:
        return state;
    }
  }

  const [count, dispatch] = useReducer(reducer, 0)

  return (
    <>
      <div className="card">
        <button onClick={() => dispatch({ type: "plus" })}>
          +1
        </button>
        {count}
        <button onClick={() => dispatch({ type: "des" })}>
          -1
        </button>
      </div>
    </>
  )
}
  1. useContext
    在跨组件层级获取数据时简化数据的代码(App -> Foo)
javascript 复制代码
import React, { useContext, useState } from 'react';

// 1. 创建 Context
const UserContext = React.createContext();

function App() {
  const [user, setUser] = useState({ name: 'Alice', age: 25 });

  return (
    // 2. 使用 Provider 共享数据
    <UserContext.Provider value={user}>
      <UserProfile />
    </UserContext.Provider>
  );
}

function UserProfile() {
  // 3. 在子组件中使用 useContext 获取 Context 的值
  const user = useContext(UserContext);

  return (
    <div>
      <h2>User Profile</h2>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
    </div>
  );
}

export default App;
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端