react hooks的基本使用

简介: react hooks学习笔记

前提:对react有一定的了解,需要react的版本16.8及以上

1、useState
作用:在函数式组件里面可以使用class的state、setState
示例:

import React, { useState } from "react";
const counter = () => {
  const [count, setCount] = useState(1); //默认设置count的值为1
  return (
    <div>
      <button click={() => setCount(count - 1)}> - </button>
      <span>{count}</span>
      <button click={() => setCount(count + 1)}> + </button>
    </div>
  )
}

2、useEffect
作用:在函数组件里面使用 class的生命周期函数,useEffect包括了class的所有生命周期函数
注意:在useEffect内使用setState,极容易导致死循环
useEffect有两个参数,一个组件可以写多个useEffect
1、useEffect第二个参数不传,就表示每一次渲染都执行,基本不会使用到
2、useEffect第二个参数传[],只会在组件渲染的第一次执行,相当于class的componentDidMount
3、useEffect第二个参数传[name,age],数组中的参数可以一个或者多个,表示name或者age改变了就会执行useEffect,name和age可以是父组件传入的props,也可以是组件的state
示例:

import React, { useState, useEffect } from "react";
const counter = (props) => {
  const { number = 1 } = props;
  const [count, setCount] = useState(number);
  useEffect(() => { //可以监听number的改变
    if(number !== count) {
      setCount(number)
    }
  }, [number]);
  return (
    <div>
      <button click={() => setCount(count - 1)}> - </button>
      <span>{count}</span>
      <button click={() => setCount(count + 1)}> + </button>
    </div>
  )
}

const Parent = () => {
  const [number, setNumber] = useState(1);
  useEffect(() => {
    setTimeout(() => {
      setNumber(10)
    }, 1000)
  }, []);
  return (
    <Counter number={number} />
  )
}

4、在useEffect中使用setInterval、事件监听等,可以通过return,在组件卸载的时候清除掉

const [count, setCount] = useState(1)
useEffect(() => {
    const timer = setInterval(() => {
      setCount(count + 1)
  }, 1000)
  return ()=> clearInterval(timer)
},[])

5、useEffect 里面使用到的state的值, 固定在了useEffect内部, 不会被改变,除非useEffect刷新,重新固定state的值

import { useState, useEffect } from "react";
const Counter = () => {
  const [count, setCount] = useState(0)
  useEffect(() => {
    console.log('use effect...',count) //输出的是0
    const timer = setInterval(() => {
      console.log('timer...count:', count) //输出的也一直是0
      setCount(count + 1)
    }, 1000)
    return ()=> clearInterval(timer)
  },[])
  return (
    <span>{count}</span>
  )
}

解决办法 useEffect的第二个参数 [] 改为 [count],可以监听count的改变,重新执行useEffect函数,拿到最新的count值

3、useRef
作用:主要操作dom
示例:点击button的时候,input获取焦点

import { useRef } from "react";
const FocusInput = () => {
  const inputRef = useRef();
  const onInputFocus = () => {
    inputRef.current.focus()
  };
  return (
    <div>
      <input ref={inputRef} />
      <button click={onInputFocus}>input获取焦点</button>
    </div>
  )
}

useRef 与 creatRef 的区别:
useRef , 它像一个变量, 类似于 this , 它就像一个盒子, 你可以存放任何东西. createRef 每次渲染都会返回一个新的引用,而 useRef 每次都会返回相同的引用。

4、useMemo
作用:有着暂存能力,父组件每次render的时候,传入子组件的值如果没有改变,阻止子组件的重新渲染(子组件必须使用memo包裹,类似purecomponent),节约性能。useMemo可以暂存值、函数和组件。
示例:

import { useMemo, useState, memo } from "react";
const Parent = () => {
  const [number, setNumber] = useState(1);
  const [name, setName] = useState('yelu');
  const data = { name }
  return ( 
    <>
      <span>{number}</span>
      <button click={() => setNumber(prev => prev + 1)}> + </button>
      <Child data={data} />
    </>
  )
}

const Child = memo(({ name }) => {
  return (
    <div>{name}</div>
  )
})

Parent组件每次点击button的时候,重新设置的number的值,然后重新render渲染,data重新赋值了一个引用对象,Child组件也会重新render渲染(即使Parent组件的name没有改变,造成了多余的渲染,性能浪费了, useMemo可以解决此问题),useMemo的第二个参数同useEffect的第二个参数。

//将上面示例的const data = {name} 改成下面的代码
const data = useMemo(() => {
  return { name }
}, [name])

//useMemo 拥有暂存能力,暂存了上一次的name结果,结果一对比上一次的name,
发现name值居然没有改变!那么这次data就不重新赋值成新的对象了!Child组件就不会重新渲染了

5、useCallback
作用:跟useMemo一样,useCallback是暂存函数的
注意:useCallback的第二个参数同useEffect的第二个参数,因为是暂存函数,所以useCallback的第二个参数一般都是 [] ,如果函数里面逻辑有依赖state的某个值,第二个参数也可以传依赖的值;
示例:

import { useCallback, useState, memo } from "react";
const Parent = () => {
  const [name, setName] = useState('yelu');
  const change = useCallback((e) => {
    setName(e.target.value)
  }, [])
  return (
    <>
      <span>{name}</span>
      <Child change={change} />
    </>
  )
}

const Child = memo(({ change }) => {
  return (
    <div>
      <input placeholder="请输入名称" change={change}
    </div>
  )
})

6、useReducer
作用:就是class里面的reducer
示例:

const reducer =(state = 0, {type})=>{
  switch (type) {
    case "add":
      return state+1
    case 'delete':
      return state-1
    default:
      return state;
  }
};

import { useReducer } from "react";
const Conuter = () => {
  const [count, dispatch] = useReducer(reducer, 0)
  return(
    <div>
      <span>{count}</span>
      <button click={() => dispatch({type: 'add'})} + </button>
      <button click={() => dispatch(type: 'delete')} - </button>
    </div>
  )
}

7、useContext
作用:跟class里面的context一样, 深层次嵌套组件间可以共享状态
示例:

import React, { useContext , useState } from "react";
const Context = React.createContext(null);

const Root = () => {
  const [count, setCount] = useState(1);
  const addCount = () => setCount(pre => pre + 1);
  return (
    <Context.Provider value={[count, addCount]}>
      <span>{count}>
      <Middle />
      <button click={addCount}>增加</button>
    </Context.Provider>
  )
}

const Middle = () => {
  const [count, addCount] = useContext(Context);
  return (
    <div>
      <span>middle...{count}>
      <Child />
      <button click={addCount}>middle增加</button>
    </div>
  )
}

const Child = () => {
  const [count, addCount] = useContext(Context);
  return (
    <div>
      <span>child...{count}>
      <Child />
      <button click={addCount}>child增加</button>
    </div>
  )
}

8、自定义hooks
自定义一个切换和设置boolean状态的hooks

import {useEffect, useState} from "react";

const useBoolean = (props = false) => {
  const [statu, setStatu] = useState(props);
  const toggle = () => setStatu(prev => !prev);
  const setTrue = () => setStatu(true);
  const setFalse = () => setStatu(false);
  
  return {statu, toggle, setTrue, setFalse}
}

export default useBoolean;

如何使用:

import useBoolean from "./useBoolean";
import React from "react";

const Hooks = () => {
  const {statu, toggle, setTrue, setFalse} = useBoolean(true);
  return (
    <div>
      <span>{statu ? '显示内容' : '隐藏内容' }</span>
      <button click={() => setTrue()}>显示</button>
      <button click={() => setFalse()}>隐藏</button>
      <button click={() => toggle()}>切换</button>
    </div>
  )
}

9、更多hooks可以关注第三方hooks库,比如umi框架的的 umijs/hooks、基于umi hooks的ahooks库

相关文章
|
前端开发 JavaScript 开发者
深入理解React Hooks:提升前端开发效率的关键
【10月更文挑战第5天】深入理解React Hooks:提升前端开发效率的关键
|
5月前
|
前端开发
轻松掌握 React Hooks:简化状态与副作用管理
轻松掌握 React Hooks:简化状态与副作用管理
208 80
|
5月前
|
前端开发
React Hooks数据获取:避免内存泄漏的实战指南
React Hooks数据获取:避免内存泄漏的实战指南
|
1月前
|
缓存 前端开发 JavaScript
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
🌟蒋星熠Jaxonic,前端探索者。专注React Hooks深度实践,从原理到实战,分享状态管理、性能优化与自定义Hook精髓。助力开发者掌握函数组件的无限可能,共赴技术星辰大海!
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
|
前端开发 JavaScript
React Hooks 全面解析
【10月更文挑战第11天】React Hooks 是 React 16.8 引入的新特性,允许在函数组件中使用状态和其他 React 特性,简化了状态管理和生命周期管理。本文从基础概念入手,详细介绍了 `useState` 和 `useEffect` 的用法,探讨了常见问题和易错点,并提供了代码示例。通过学习本文,你将更好地理解和使用 Hooks,提升开发效率。
240 4
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
前端开发 JavaScript API
探索React Hooks:前端开发的革命性工具
【10月更文挑战第5天】探索React Hooks:前端开发的革命性工具
|
前端开发 JavaScript
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
|
前端开发 开发者
React 提供的其他重要 Hooks
【10月更文挑战第20天】React 提供了一系列强大的 Hooks,除了 `useRef` 之外,还有许多其他重要的 Hooks,它们共同构成了函数式组件开发的基础。
215 62
|
12月前
|
前端开发
React Hooks:从基础到进阶的深入理解
React Hooks:从基础到进阶的深入理解
258 2