当前位置: 首页 > article >正文

一些常用的react hooks以及各自的作用

一些常用的react hooks以及各自的作用

  • 一、React Hooks是什么
  • 二、一些常用的Hooks以及各自的作用
    • 1、useState
    • 2、useEffect
    • 3、useContext
    • 4、useMemo
    • 5、useCallback
    • 6、useReducer
    • 7、useRef

一、React Hooks是什么

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性

至于为什么引入hook,官方给出的动机是解决长时间使用和维护react过程中常遇到的问题,例如:

  • 难以重用和共享组件中的与状态相关的逻辑
  • 逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 local state 时,每个生命* 周期函数中可能会包含着各种互不相关的逻辑在里面
  • 类组件中的this增加学习成本,类组件在基于现有工具的优化上存在些许问题
  • 由于业务变动,函数组件不得不改为类组件等等

在以前,函数组件也被称为无状态的组件,只负责渲染的一些工作

因此,现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理

二、一些常用的Hooks以及各自的作用

1、useState

创建数据状态,方法里的参数为state默认的值,返回值是一个数组,第一个值为当前的state,第二个值为更新state的函数

import React, { useState } from 'react';

function Example() {
  // 声明一个叫 "count" 的 state 变量
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p >
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

2、useEffect

可以进行带有副作用的操作,useEffect第一个参数接受一个回调函数,第二个参数是一个数组,数组元素指定特定值是否在两次渲染中发生变化,没有变化则跳过effect的调用

import { useEffect, useState } from "react";
export default function App() {
  const [count, setCount] = useState(0)
  const handleIncrement = () => setCount(count + 1)
  const handleDecrement = () => setCount(count - 1)
  useEffect(() => {
    console.log('useEffect');
  }, [count])

  return (
    <div style={{ padding: 10 }}>
      <button onClick={handleIncrement}>+</button>
      <span>{count}</span>
      <button onClick={handleDecrement}>-</button>
    </div>
  );
}

3、useContext

用作组件通信

import { createContext, useContext } from "react";

export function Section({ children }) {
  const level = useContext(LevelContext);
  return (
    <section className="section">
      <LevelContext.Provider value={level + 1}>{children}</LevelContext.Provider>
    </section>
  );
}

export function Heading({ children }) {
  const level =  useContext(LevelContext);
  switch (level) {
    case 1:
      return <h1>{children}</h1>;
    case 2:
      return <h2>{children}</h2>;
    case 3:
      return <h3>{children}</h3>;
    case 4:
      return <h4>{children}</h4>;
    case 5:
      return <h5>{children}</h5>;
    case 6:
      return <h1>{children}</h1>;
    default:
      throw Error("未知的 level: " + level);
  }
}

const LevelContext = createContext(0);

export default function App() {
  return (
    <div>
      <Section>
        <Heading>主标题</Heading>
        <Section>
          <Heading>副标题</Heading>
          <Heading>副标题</Heading>
          <Heading>副标题</Heading>
          <Section>
            <Heading>子标题</Heading>
            <Heading>子标题</Heading>
            <Heading>子标题</Heading>
            <Section>
              <Heading>子子标题</Heading>
              <Heading>子子标题</Heading>
              <Heading>子子标题</Heading>
            </Section>
          </Section>
        </Section>
      </Section>
    </div>
  );
}

4、useMemo

用作数据缓存

import { useMemo, useState } from "react";

function DoSomeMath({value}){
  const result = useMemo(() => {
    console.log('DoSomeMath执行了');
    let result = 0
    for(let i = 0; i < 1000000; i++){
      result += value * 2
    }
    return result
  }, [value])
  return (
    <div>
      <p>输入内容:{value}</p>
      <p>经过复杂计算的数据:{result}</p>
    </div>
  )
}

export default function App() {
  const [inputValue, setInputValue] = useState(5)
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>count的值为:{count}</p>
      <button onClick={() => setCount(count  + 1)}>
        点击更新
      </button>
      <br/>
      <br/>
      <input 
        type="number"
        value={inputValue}
        onChange={(e) => setInputValue(parseInt(e.target.value))}
      />
      <DoSomeMath value={inputValue}/>
    </div>
  );
}

5、useCallback

用作函数缓存

import { memo, useCallback, useState } from "react";

// memo将组件变更为一个记忆组件,如果向这个组件传入的prop没有出现变话,它就不会受到父组件更新的影响
const Button = memo(function ({ onClick }) {
  console.log("Button渲染了");
  return <button onClick={onClick}>子组件</button>;
}); 

export default function App() {
  const [count, setCount] = useState(0)
  const handleClick = useCallback(() => {
    console.log("点击按钮");
  }, []);
  const handleUpdate = () => {
    setCount(count + 1)
  }
  return (
    <div>
      <p>Count:{count}</p>
      <button onClick={handleUpdate}>点击</button>
      <br />
      <Button onClick={handleClick} />
    </div>
  );
}

6、useReducer

用作state的统一管理状态,可用useState代替

import { useReducer } from "react";
function countReducer(state, action){
  switch (action.type){
    case "increment":
      return state + 1
    case "decrement":
      return state - 1
    default: 
      throw new Error()
  }
}
export default function App(){
  // 计数器
  // const [count, setCount] = useState(0)
  // const handleIncrement = () => setCount(count + 1)
  // const handleDecrement = () => setCount(count - 1)
    const [state, dispatch] = useReducer(countReducer, 0);
    const handleIncrement = () => dispatch({ type: "increment" });
    const handleDecrement = () => dispatch({ type: "decrement" });

  return (
    <div style={{ padding: 10 }}>
      <button onClick={handleIncrement}>+</button>
       {/* <span>{count}</span> */}
      <span>{state}</span>
      <button onClick={handleDecrement}>-</button>
    </div>
  );
}

7、useRef

用作获取DOM结构和引用之前的状态值

// react hooks,useRef,引用之前的状态值
import { useRef, useState } from "react";

export default function App(){
  const [count, setCount] = useState(0)
  const prevCount = useRef()

  function handleClick(){
    prevCount.current = count
    setCount(count + 1)
  }

  return (
    <div style={{ padding: 10 }}>
      <p>最新的count:{count}</p>
      <p>上次的count:{prevCount.current}</p>
      <button onClick={handleClick}>增大的count</button>
    </div>
  );
}
// react hooks,useRef,引用页面中的标签
import { useRef } from "react";

export default function App(){
  const inputRef = useRef(null)

  function handleClick(){
    inputRef.current.focus()
  }

  return (
    <div style={{ padding: 10 }}>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>增大的count</button>
    </div>
  );
}
// react hooks,useRef,引用页面中的其他组件进行子组件功能访问
import { forwardRef, useImperativeHandle, useRef } from "react";
const Child = forwardRef(function (props, ref) {
  useImperativeHandle(ref, () => ({
    // 暴露父组件的方法
    myFn: () => {
      console.log("子组件的myFn方法");
    },
  }));
  return <div>子组件</div>;
});

export default function App() {
  const childRef = useRef();
  function handleClick() {
    childRef.current.myFn()
  }

  return (
    <div>
      <Child ref={childRef} />
      <button onClick={handleClick}>按钮</button>
    </div>
  );
}

http://www.kler.cn/a/379985.html

相关文章:

  • 使用 SSH 蜜罐提升安全性和记录攻击活动
  • 解析JSON字符串的多种方式
  • 数据库操作(php+mysql)
  • HarmonyOS 移动应用开发
  • 1、Qt6 Quick 简介
  • 云原生+AI核心技术&最佳实践
  • 【漏洞复现】泛微OA E-Office group_xml.php SQL注入漏洞
  • Vue项目与IE浏览器的兼容性分析(Vue|ElementUI)
  • Web大学生网页作业成品——和平精英网页设计与实现(HTML+CSS+JS)(4个页面)
  • MATLAB——矩阵操作
  • CSS基础学习篇——选择器
  • ThreeJS创建一个3D物体的基本流程
  • Github 2024-11-01 开源项目月报 Top19
  • 信息学科平台开发:Spring Boot核心技巧与实践
  • 银行金融知识竞赛活动策划方案
  • 回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测
  • 上云管理之Git/GitHub/GitLab 详解(一)
  • 中汽测评观察 亲子出行健康为先,汽车健康用材成重要考量
  • PHP常量
  • Unity 生命周期的事件顺序
  • 32.Redis高级数据结构HyperLogLog
  • [数组排序] 0912. 排序数组
  • 使用python与Flask对pdf格式文件进行删改
  • 【新手入门软件测试--该如何分辨前后端问题及如何定位日志--前后端问题分辨与日志定位查询问题】
  • 论文笔记(五十四)pi0: A Vision-Language-Action Flow Model for General Robot Control
  • 使用MongoDB Atlas构建无服务器数据库