React Hooks 组件化开发(常用)

news2024/11/23 8:57:27

本文章视频地址:视频链接

一、React组件分类

在这里插入图片描述

二、Hook函数概览

Hook 是 React 16.8 的新增特性!并且只能运用到函数组件中!
在这里插入图片描述

1.useState

作用:在函数组件中使用状态,修改状态值可让函数组件更新,类似于类组件中的setState
语法: const [state,setState] = useState(initialState); 返回一个 state,以及更新 state 的函数

import React, { useState } from "react";
export default function Demo(props) {
    let [num, setNum] = useState(10);
    const handler = () => {
        setNum(num + 1);
    };
    return <div>
        <span>{num}</span>
        <button onClick={handler}>新增</button>
    </div>;
};

2.useEffect

作用:在函数组件中使用生命周期函数
语法:具备很多情况 useEffect([callback],[dependencies])

import React, { useState, useEffect } from "react";
export default function Demo() {
    let [num, setNum] = useState(10),
        [x, setX] = useState(100);

    /* 
     在组件 第一次渲染完 && 每一次更新完 调用 
     等同于 componentDidMount && componentDidUpdate
    */
    useEffect(() => {
        console.log('@1', num, x);
    });

    /* 
     只在组件 第一次渲染完 调用 
     等同于 componentDidMount
    */
    useEffect(() => {
        console.log('@2', num, x);
    }, []);

    /* 
     第一次渲染完 以及 依赖的状态发生改变 时调用
    */
    useEffect(() => {
        console.log('@3', num);
    }, [num]);

    /* 
     返回的函数将在 组件卸载后 被调用
     等同于 componentWillUnmount
     */
    useEffect(() => {
        return () => {
            console.log('@4');
        };
    }, []);

    return <div>
        <span>{num}</span>
        <button onClick={() => { setNum(num + 1); }}>处理</button>
        <br />
        <span>{x}</span>
        <button onClick={() => { setX(x + 1); }}>处理</button>
    </div>;
};

【注意点1:】只能在函数最外层调用 Hook,不要在循环、条件判断或者子函数中调用。

import React, { useState, useEffect } from "react";
export default function Demo() {
    let [num, setNum] = useState(10);
    if (num >= 10) {
        // Error:React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render  react-hooks/rules-of-hooks
        useEffect(() => {
            console.log('@1', num);
        });
    }
    return <div>
        <span>{num}</span>
        <button onClick={() => { setNum(num + 1); }}>处理</button>
    </div>;
};

【注意点2:】异步获取数据

不能直接对[callback]设置async,因为它只能返回一个函数(或者不设置返回值)

import React, { useState, useEffect } from "react";
const queryData = () => {
    return fetch('/api/subscriptions/recommended_collections')
        .then(response => {
            return response.json();
        });
};
export default function Demo() {
    let [data, setData] = useState([]);
    /* // Warning: useEffect must not return anything besides a function, which is used for clean-up.
    useEffect(async () => {
        let result = await queryData();
        setData(result);
        console.log(result);
    }, []); */
    useEffect(() => {
        const next = async () => {
            let result = await queryData();
            setData(result);
            console.log(result);
        };
        next();
    }, []);
    return <div>
        ...
    </div>;
};

3.useRef

在这里插入图片描述
简单来说,useRef就像一个储物箱,你可以随意存放任何东西,再次渲染时它会去储物箱找,createRef每次渲染都会返回一个新的引用,而useRef每次都会返回相同的引用。

import React, { useState, useEffect, useRef, createRef } from "react";
let prev;
export default function Demo() {
    const [num, setNum] = useState(0);
    const btnBox = useRef(null); //换成createRef也是可以的
    if (!prev) {
        prev = btnBox;
    } else {
        console.log(prev === btnBox);
    }
    useEffect(() => {
        console.log(btnBox.current);
    }, []);
    return <div>
        <span>{num}</span>
        <button ref={btnBox} onClick={() => setNum(num + 1)}>按钮</button>
    </div>;
};

4.useContext

作用:跨组件共享数据
说明:在没有hook之前,我们通常都会通过 xxxContext.Provider 和 xxxContext.Consumer 的方式来传递和获取context的值,使用hook之后,传递context的方式不变,但子元素获取context的方式变得更加的简洁。

// 以前的定义方式
const CountContext = React.createContext()
 <CountContext.Provider value={{ count: 10 }}>
     <...自定义的组件>
 </CountContext.Provider>
// 子元素
<CountContext.Consumer>
    { value => { console.log(value.count) }} //10
</CountContext.Consumer>


//使用context的获取方式
const countObj = useContext(CountContext)
console.log(countObj.count) // 10

5.useReducer

作用:useReducer相当于是useState的升级版,与useState类似,都是用来保存状态,但它的不同点在于可以定义一个reducer的纯函数,来处理复杂数据。

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

6.useCallback

作用:函数式组件中,每一次更新状态,自定义的函数都要进行重新的声明和定义,如果函数作为props传递给子组件,会造成子组件不必要的重新渲染,有时候子组件并没有使用到父组件发生变化的状态,此时可以使用useCallback来进行性能优化,它会为函数返回一个记忆的值,如果依赖的状态没有发生变化,那么则不会重新创建该函数,也就不会造成子组件不必要的重新渲染。

父组件:

import React, { useState, useCallback, memo } from "react";
export default function Demo() {
    let [val, setVal] = useState('');
    const handler1 = () => {
        setVal('哈哈哈');
    };
    const handler2 = useCallback(() => {
        setVal('呵呵呵');
    }, []);
    return <div>
        <input type="text" value={val}
            onChange={ev => {
                setVal(ev.target.value);
            }} />
        <Child1 handler={handler1} />
        <Child2 handler={handler2} />
    </div>;
};

子组件Child1:

class Child1 extends React.PureComponent {
    render() {
        console.log('child1 render');
        return <div>
            <button onClick={this.props.handler}>处理1</button>
        </div>;
    }
}

子组件Child2:

// 如果子组件是函数组件,则需要useCallback和memo配合使用
const Child2 = memo(function Child2({ handler }) {
    console.log('child2 render');
    return <div>
        <button onClick={handler}>处理2</button>
    </div>;
});

7.useMemo

作用:useMemo也是返回一个记忆的值,如果依赖的内容没有发生改变的话,这个值不会发生变化。
注意:useMemo与useCallback的不同点在于useMemo需要在传入的函数里需要return 一个值。

import React, { useState, useMemo } from "react";
export default function Demo() {
    let [x, setX] = useState(10),
    const cacheVal = useMemo(() => {
        // 大量的计算...
        return x;
    }, [x]);
    return <div>
        <span>{cacheVal}</span>
        <button onClick={() => setX(x + 1)}>处理</button>
    </div>;
};

8.自定义Hook

使用自定义hook可以将某些组件逻辑提取到可重用的函数中

import React, { useState } from "react";
const usePartState = function usePartState(initial) {
    let [state, setState] = useState(initial);
    const setPartState = (partState) => {
        setState({
            ...state,
            ...partState
        });
    };
    return [state, setPartState];
};
export default function Demo() {
    let [state, setState] = usePartState({
        x: 10,
        y: 20
    });
    return <div>
        <span>{state.x}</span>
          
        <span>{state.y}</span>
        <button onClick={() => {
            setState({
                x: state.x + 1
            });
        }}>处理x</button>
    </div>;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/617623.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙初识

学习官网&#xff1a;https://www.harmonyos.com/cn/develop 准备 注册&#xff0c;安装软件(node:12, DevEco Studio)&#xff1a; 在实际开发中node最好使用nvm进行版本管理。 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-00000010…

ChatGPT-Plugins-Searchable

ChatGPT Plus 用户应该都知道Plus已经开放了插件功能&#xff0c;但是在插件商店里存在一个较大的问题插件数量超过100款&#xff0c;却没有便捷的搜索功能。 而我们在查找一款插件时&#xff0c;需要从插件商店的第一页点击到最后一页一个个找&#xff0c;显然这非常的麻烦。 …

驱动开发--驱动模块

目录 1.驱动模块 hello.c Makefile 2.内核中的打印函数&#xff08;编写第一个驱动程序&#xff09; Source Insight 使用&#xff1a; 3.打印函数编写 分析 4、驱动的多文件编译 5、模块传递参数 6、安装好驱动之后如何传参&#xff1f; 7、字符设备驱动 8、字符设…

chatgpt赋能python:Python如何突破VIP限制

Python如何突破VIP限制 在这个数字内容时代&#xff0c;我们经常使用各种网站和应用程序来获取视频、音乐、软件等数字资源。但是&#xff0c;某些资源可能受到VIP限制&#xff0c;这意味着我们需要付费才能获得完整的访问权限。但是&#xff0c;如果你了解Python编程&#xf…

Agile | 聊聊敏捷开发

什么是敏捷开发 敏捷开发是一种迭代和增量的项目管理方法&#xff0c;优先考虑适应性、协作和快速交付&#xff0c;而不是遵循严格的计划[0]。它是在《敏捷软件开发宣言》和《12项原则》中表达的一组价值观和原则[1]。敏捷是基于这些价值观和原则的一组框架和实践的总称。敏捷…

【数据库】修改数据库密码及端口

一、修改MySQL配置文件 想要在没有密码的状态下修改MySQL的密码&#xff0c;必须跳过MySQL登录时的登录密码权限的验证&#xff0c;取消掉这个验证的方式如下&#xff1a; 1、找到MySQL的安装文件中的my.ini文件 一般人应该能找到的吧&#xff0c;配置MySQL的环境变量中也有安…

关于数据中心机房动环监控系统的应用与设计 安科瑞 许敏

摘 要&#xff1a; 机房动力和环境监控系统是对分布的精密机房及通信局&#xff08;站&#xff09;内的电源、空调、油机、蓄电池、高低压配电等多种设备和环境的各种参数、图像、声音等进行遥测、并对设备进行集中监控、集中维护和集中管理&#xff0c;是现代化机房管理手段和…

【Leetcode -138.复制带随机指针的链表 -2130.链表最大孪生和】

Leetcode Leetcode -138.复制带随机指针的链表Leetcode -2130.链表最大孪生和 Leetcode -138.复制带随机指针的链表 题目&#xff1a;给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构…

chatgpt赋能python:Python如何设置画笔颜色

Python如何设置画笔颜色 在Python中&#xff0c;有很多库可以用来画图&#xff0c;比如常用的Matplotlib、Seaborn和Plotly等等&#xff0c;但无论是哪种库&#xff0c;设置画笔颜色都是非常基础且重要的操作&#xff0c;因为它可以让我们更好地展示数据图表&#xff0c;突出重…

【TCP/IP】基于UDP的服务器端/客户端实现 II - 实践与实现

基于UDP的回声服务器端/客户端 结合之前基于TCP实现的回声服务器&#xff0c;我们尝试再用UDP来完成对回声服务器/客户端的设计。 echo_server: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa…

内蒙古自治区关于加快充换电基础设施建规划 安科瑞 许敏

摘要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升电动汽车充电基础设施服务保障能力的实施意见》&#xff08;发…

异常值检验(t分布查表)、方差分析

异常值检验 T-test 参考&#xff1a;1.ttest和ttest2 区别 2. ttest在 matlab 3.T test分布表 单侧 方差分析&#xff08;ANOVA&#xff09; Def: 方差分析&#xff08;analysis of variance, ANOVA&#xff09;是一种统计检验&#xff0c;用于检验两组或更多组样本的均值是…

PRL:上海交大张文涛团队实现量子材料相关突破

来源&#xff1a;上海交通大学 近期&#xff0c;上海交通大学物理与天文学院张文涛研究组利用自行研制的高能量和高时间分辨率角分辨光电子能谱系统对量子材料1T-TiSe₂电子结构进行了超快激光操控研究。利用超快光激发与电荷密度波相有关的相干声子&#xff0c;引起晶格内原子…

高压放大器在微波光子雷达中的应用有哪些

微波光子雷达是一种新型的雷达技术&#xff0c;它利用微波和光子相结合的方式进行探测和成像。在微波光子雷达系统中&#xff0c;高压放大器作为一个关键的组件&#xff0c;主要用于对微波信号进行放大&#xff0c;以增强雷达系统的探测能力和成像精度。本文将详细介绍高压放大…

20230606夏新(Amoi)的4K显示器D320B2000的亮点检测

20230606夏新&#xff08;Amoi&#xff09;的4K显示器D320B2000的亮点检测 2023/6/7 0:14 https://item.jd.com/63690000655.html 夏新&#xff08;Amoi&#xff09;电脑显示器高清家用办公电竞吃鸡游戏液晶监控直播大屏便携显示屏幕 32英寸【直面 4k/144hz双模式 全面屏】黑 …

Linux内核文件写入流程

文本代码基于Linux 5.15 。 当用户层调用write 去做写入&#xff0c; linux 内核里面是如何处理的&#xff1f; 本文以exfat 为例&#xff0c; 讨论这个流程 入口函数 write 系统调用的定义如下&#xff1a; fs/read_write.c ssize_t ksys_write(unsigned int fd, const ch…

数据库期末复习(7.2)查询优化

查询优化的概述 商用数据库花了很多的资金投入到查询优化。 查询优化的分类 逻辑查询优化 物理查询优化 比逻辑查询计划多了怎么去执行的方式,为的是数据操作速度更快 逻辑查询优化的三种关键技术 在科学研究的道路上我们往往不是一帆风顺的,人的认识也是局限的,但是我…

SciencePub学术 | 计算机科学类重点SCIEI征稿中

SciencePub学术刊源推荐: 计算机科学类SCI&EI征稿中&#xff01;录用率高&#xff0c;自引率低&#xff0c;进展顺利。信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 【期刊简介】IF&#xff1a;4.0-4.5↑&#xff0c; JCR 2区&#xff0c;中科院3区…

抖音seo源码·源代码搭建·支持二开(开源)系统

抖音seo源码&#xff0c;抖音seo系统&#xff0c;抖音搜索排名&#xff0c;源码系统开发 场景&#xff1a;公认的视频发布功能可是必备的&#xff0c;智能剪辑和智能客服更不用说&#xff0c;作为产品中粉丝转化的重要一环也是必不可少的 抖音seo源码开发&#xff0c;即抖音搜…

Firefox插件(拓展)开发

目录 0、一些概念 1、创建一个项目 2、创建内容脚本 3、将拓展临时添加到浏览器中进行测试 3-1、CtrlShiftA 或&#xff1a; 3-2、选择调试附加组件 3-3、选择临时加载附加组件 3-4、选择我们项目中的 manifest.json 文件打开 3-5、如果打开成功&#xff1a; 4、继续开…