react-17-hook-基础

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

1. 前言


what Hook

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


2. why


之前的组件形式缺点

  1. 函数组件一般是无状态组件
  2. 类组件可以有状态,也可以无状态
  3. 组件之间复用状态逻辑很难,组件维护越来越复杂
  4. class组件中的 this难以理解


3. Hook 基本概念


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

  1. 避免地狱式嵌套,可读性提高
  2. 函数式组件,比class组件更容易理解
  3. UI和逻辑更容易分离
  4. 基本不需要 this


4. 引入hook之前的代码问题


简单的计数器案例


function MyCom(){
            let count = 0
            function add(){
                count ++
                console.log(count)
            }
            return (
                <div>
                    {count}
                    <button onClick={add}>点我</button>
                </div>
            )
        }
        ReactDOM.render(
            <MyCom/>,
            document.getElementById("app")
        )

点击按钮界面变量不跟着变


5.  Hooks 有哪些常用的API


Hooks让我们的函数组件拥有了类组件的特性,例如组件内的状态、生命周期

1.useState     组件内的状态

2.useEffect       生命周期

3.其他


6. 语法-State



const [state,setState] = useState(initialState)

1.state为变量

2.initialState state变量的初始值

3.setState 修改state值的方法

4.setState异步执行


7.hook -useState


包含--基本类型写法

包含--引用类型写法


function MyCom(){
// 声明一个叫 count 的state变量,  初始值为0
            let [count, setCount] = React.useState(0)
// 声明一个 叫obj的 state变量 初始值为空对象
            let [obj, setObj] = React.useState({})
            function add(){
// 基本类型的修改
                setCount(++count)
// 引用类型的修改
                setObj({
                    name: 'a'+count
                })
                console.log(count)
            }
            return (
                <div>
                    {count}-{obj.name}
                    <button onClick={add}>点我</button>
                </div>
            )
        }

在函数组件中通过useState实现函数内部维护state,参数为state默认的值,返回值是一个数组,

第一个值为当前的state

第二个值为更新state的函数


8 类组件  VS 函数式组件


1.state声明方式:

在函数组件中通过useState 直接获取,类组件通过constructor构造函数中设置

2.state读取方式:

在函数组件中直接使用变量,类组件通过this.state.count的方式获取

3.state更新方式:

在函数组件中通过setCount更新,类组件通过this.setState()

总结就是useState使用起来更为简洁,减少了this指向不明确的情况


9. hook-钩子 -useEffect


9.1语法

React.useEffect(参数1,参数2)

参数1 是回调函数

参数2 是参数1 这个函数监听的变量

9.2 useEffect 相当于3个钩子的综合

1.componentDidMount

2.componentDidUpdate

3.componentWillUnMount

9.3 分析

参数2 为空 不写:  DidMount+DidUpdate

在第一次渲染和更新之后都会执行

参数2 空数组[] ,DidMount

第一次渲染后

参数2 [变量], 监听变量的改变 componentDidUpdate

React 将对前一次渲染的变量值count和后一次渲染的 count 值进行比较

9.4 代码


function MyCom(){
            let [count, setCount] = React.useState(0)
            let [obj, setObj] = React.useState({})
            function add(){
                // setCount(++count)
                setObj({
                    name: 'a'+count
                })
                console.log(count)
            }
            React.useEffect(() => {
               console.log("初始化或更新1")
            })
            React.useEffect(() => {
               console.log("初始化2")
            }, [])
            React.useEffect(() => {
               console.log("初始化或count更新3")
            }, [count,obj])
            return (
                <div>
                    {count}-{obj.name}
                    <button onClick={add}>点我</button>
                </div>
            )
        }

这个建议 还是自己写写,因为代码本身也很简单


10. 清除函数


回调函数中可以返回一个清除函数,这是effect可选的清除机制,相当于类组件中componentwillUnmount生命周期函数,可做一些清除副作用的操作,比如定时器


// 创建响应数据以及修改方法
        let [num,setNum]=useState(20);
        // 会在更新之前 执行指定的销毁函数
        // 防止初始化的代码 重复绑定  定时器
        useEffect(()=>{
            console.log("useEffect")
            // 绑定定时器 让num递增
            let timer=setInterval(()=>{
                console.log("定时器");
                num++;
                setNum(num);//num发生变化
            },1000);
            return ()=>{//销毁 
                clearInterval(timer);
            }
        })



11. 总结


1.每调用useHook一次都会生成一份独立的状态

2.通过自定义hook能够更好的封装我们的功能

3.useEffect相当于componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个生命周期函数的组合


12.其他hooks


useReducer

useCallback

useMemo

useRef


13. 这里再梳理个  useReducer


其实就是 useState的替代版 主要用来 结合redux  中的reducer

13.1 简单的看下 store 中 redux的结构


import { createStore } from "redux";
let  defaultState = {
    counter:0
} 
export const reducer = (state=defaultState,{type,payload=10})=>{
    switch (type){
        case "counter/incremented":{
            let tempState = JSON.parse(JSON.stringify(state));
            tempState.counter += payload
            return tempState
        }
        case "counter/decremented":{
             return{
                 ...state,
                 counter:state.counter - payload
             }
        }
        default:{
            console.log("switch  默认")
            return state
        }
    }
}
let store = createStore(reducer)
export default store


13.2 使用 useReducer


import { useState, useEffect ,useReducer} from 'react';
import {reducer} from "../store"
function HookPage() {
  const [state, dispatch] = useReducer(reducer, {counter:99})
  } 
  return (
    <div className="App">
      <h1>{state.counter}</h1>
      <button onClick={()=>{
        dispatch({type:"counter/decremented",payload:100})
      }}> redux</button>
    </div>
  );
}
export default HookPage;


13.3 分析

useReducer()

参数1: 就是reducer

参数2:就是初始值

参数3:是个初始化的回调函数


14. 完整的 组件内使用 hook



import { useState, useEffect ,useReducer} from 'react';
import {reducer} from "../store"
function HookPage() {
  let [counter, setCounter] = useState(0)
  let [person, setPerson] = useState({ name: "yzs" })
  const [state, dispatch] = useReducer(reducer, {counter:99})
  function increase(v) {
    counter += v
    setCounter(counter)
  }
  function update() {
    setPerson({
      name: "郑州"
    })
  } 
  // **************钩子
  useEffect(() => {
    console.log("初始化或者更新")
  })
  useEffect(() => {
    console.log("[]  初始化")
  },[])
  useEffect(() => {
    console.log("初始化或 对应的值变化")
  },[counter,person])
  return (
    <div className="App">
      <h1>{counter}</h1>
      <button onClick={() => {
        increase(10)
      }}>增加</button>
      <hr />
      <h1>{person.name}</h1>
      <button onClick={update}> name</button>
      <hr/>
      <h1>{state.counter}</h1>
      <button onClick={()=>{
        dispatch({type:"counter/decremented",payload:100})
      }}> redux</button>
    </div>
  );
}
export default HookPage;



15. 总结性hook


可参考这篇文章 react常用-hook总结




相关文章
|
7月前
|
数据采集 搜索推荐 数据可视化
六大电子表单工具深度对比:选对表单工具,告别低效
本文将深入分析对比金数据、腾讯问卷、草料二维码等电子表单工具功能、应用场景、优劣势上的差异,希望能为数字化转型关口的中小企业,提供一份更具参考价值的指南
六大电子表单工具深度对比:选对表单工具,告别低效
|
7月前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能与ai有什么区别
本文探讨了“人工智能”与“AI”在语义、使用场景及技术侧重点上的差异,强调理解这些差异对把握技术发展的重要性。文中分析了两者的学术与通俗应用场景,并结合生成式人工智能认证项目(由培生于2024年推出),说明如何通过理论与实践结合,规避AI局限性,推动技术创新。最终呼吁在概念辨析中探索人工智能的未来潜力。
|
9月前
|
搜索推荐 小程序 数据挖掘
互联网运营为何必须做好用户行为数据分析
近年来互联网运营已经成为大多数企业不可或缺的一部分。随着互联网技术的不断发展和数字化转型的推进,越来越多的企业都在加速向互联网运营转型,而在这一过程当中,分析用户行为数据是至关重要的。接下来,我们就来探讨一下其中的原因。
|
JavaScript 前端开发 调度
事件驱动模型
【10月更文挑战第7天】事件驱动模型
522 7
|
C# 开发者 Windows
不可不知的WPF转换(Transform)
【9月更文挑战第14天】在 Windows Presentation Foundation(WPF)中,转换(Transform)是一种强大的工具,允许开发者以多种方式操纵图形和界面元素的外观与位置。主要类型包括平移、旋转、缩放和倾斜转换。通过组合这些转换,可以实现更复杂的效果,并且可以与 WPF 的动画系统结合,创建动态界面效果。掌握 WPF 转换是成为优秀开发者的必备技能之一。
290 6
|
开发框架 .NET API
.NET 体系概览图集 - 2024 最全总结
.NET Core 是一个免费、跨平台、开源的开发平台,用于一站式构建不同类型的应用程序。 .NET Core 是以 .NET Framework 为基础,但是经过重新设计、实现的的新一代框架,实现了原 .NET Framework 中的几乎所有功能,核心特点就是开源、跨平台。
897 0
.NET 体系概览图集 - 2024 最全总结
|
域名解析 开发框架 Ubuntu
Caddy VS Nginx,谁才是真正的王者
Caddy 2 is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go.
8155 1
Caddy VS Nginx,谁才是真正的王者
|
网络协议 网络架构
IP地址划分知识点总结
IP地址划分知识点总结
769 1
|
机器学习/深度学习 并行计算 算法
掌握XGBoost:GPU 加速与性能优化
掌握XGBoost:GPU 加速与性能优化
2297 0
|
网络协议 Linux 网络安全
Centos7 防火墙策略rich-rule 限制ip访问-----图文详解
Centos7 防火墙策略rich-rule 限制ip访问-----图文详解
2961 0