React-Hooks类别函数的用法

反应钩

useState

useState是个反应自带的一个钩子函数,它的作用就是声明状态变量。useState这个函数接收的参数是我们的状态初始值(初始状态),它返回了一个数组,这个数组的第[0]项是当前的状态值,第[1]项是可以改变状态值的方法函数。

import React, { useState } from 'react';

function Example() {
    const [age, setAge] = useState(18);
    const [money, setMoney] = useState(1000);
    return (
        <div>
            <button onClick={() => { setAge(age + 1) }}>{age}</button>
            <button onClick={() => { setMoney(money + 1) }}>{money}</button>
        </div>
    )
}
export default Example;

useEffect

如果你熟悉React class的生命周期函数,你可以把useEffect Hook看做componentDidMount,componentDidUpdate和componentWillUnmount这三个函数的组合。使用useEffect,可以直接在函数组件内部处理生命周期事件。

useEffect使用需要注意的地方

  • 有两个参数的回调和依赖性
  • 如果依赖项不存在,那么回调每次渲染都会执行
  • 如果依赖项存在,只有当它发生了变化,回调才会执行
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';

function useEffectTest() {
  useEffect(() => {
      
    // 默认情况下,每次渲染后都会调用该函数
    console.log('render!');

    // 如果要实现 componentWillUnmount,
    // 在末尾处返回一个函数
    // React 在该函数组件卸载前调用该方法
    // 其命名为 cleanup 是为了表明此函数的目的,
    // 但其实也可以返回一个箭头函数或者给起一个别的名字。
    return function cleanup () {
        console.log('unmounting...');
    }
  })  
  return "useEffectTest";
}

停止重新重新渲染都会执行useEffect如果希望效果在运行,可以提供第二个参数-值表。将其视为该效果的依赖关系。如果其中一个依赖项自上次更改后,effect将再次运行。

初步有数据的副本:

const [value, setValue] = useState(0);

useEffect(() => {
  // 仅在 value 更改时更新
  console.log(value);
  // 仅在组件卸载时更新
  return () => {
            console.log('组件卸载'+{ value })
  }
}, [value]) 

初步空洞

const [value, setValue] = useState(0);

useEffect(() => {
  // 仅在第一次渲染时更新
  console.log(value);
  // 仅在组件卸载时更新
  return () => {
            console.log('组件卸载'+{ value })
  }
}, []) 

useContext

useContext可以实现共享状态最大的改变是可以在使用Counter的时候不必在包裹Children了,比方说我们先创造了一个副本,这个主体里头有一个称为count的状态,以及一个修改count的方法setCount

在父组件中,使用createContext创建上下文并导出,然后通过值传递给子组件

import React, { createContext, useState } from 'react';
import { Counter } from './Counter'
// 创建一个上下文,这个上下文要导出
export const CountContext = createContext()

function UseContext() {
    const [count, setCount] = useState(0)
    return (
        <div>
            {/* 使用创建的上下文,数据通过 value 传递给子组件,这里我们传递了一个对象 */}
            <CountContext.Provider value={{count,setCount}}>
                <Counter />
            </CountContext.Provider>
        </div>
    )
}

export default UseContext
在子组件中,引入父组件创建的一部分,然后使用useContext接收父组件通过value传递的值
import React, { useContext } from 'react';
// 这里获取父组件的上下文
import { CountContext } from './index'
export function Counter() {
    // 通过 useContext 获取父组件传递的内容(d对象解构)
    const { count, setCount } = useContext(CountContext)
    return (
        <div>
            <h2>{count}</h2>
            <button onClick={() => { setCount(count + 1) }}>count</button>
        </div>
    )
}

useReducer

Redux的核心概念是,组件发出action与状态管理器通信。状态管理器收到的action以后,使用Reducer函数算出新的状态

  • 简单来说reducer是一个函数(状态,动作)=> newState:接收当前应用的状态和触发的动作action,计算并返回最新的状态。

useReducer的作用就是创造了一个状态管理器,它接收一个reducer和初始的state值。它返回了一个数组,这个数组的第[0]项是当前的state,第[1]项是可以改变state的方法函数dispatch,它会传递一个action给状态管理器。

const [状态,调度] = useReducer(reducer,initialState)

import React, { useReducer } from 'react';

// 创建的 reducer
function reducer(state, action) {
    switch (action.type) {
        case 'add':
            return { count: state.count + 1 };
        case 'del':
            return { count: state.count - 1 };
        default:
            return state;
    }
}

function UseReducer() {
    const initialState = { count: 0 }
    // 利用 reducer 和 初始state 创建一个状态管理器,返回 state 和 dispatch
    const [state, dispatch] = useReducer(reducer, initialState)
    return (
        <div>
            <p>{state.count}</p>
            {/* 利用 dispatch 传递一个 action 给状态管理器 */}
            <button onClick={()=>{dispatch({type:'add'})}}>add</button>
            <button onClick={()=>{dispatch({type:'del'})}}>del</button>
        </div>
    )
}

export default UseReducer;

通过useReducer和useContext可以实现redux,useReducer创建状态管理器,useContext将管理器传递给所有的子类(通过useContext传递状态和调度)

useMemo

useMemo使用函数的形式来声明组件,失去了shouldCompnentUpdate(在组件更新之前)这个生命周期,从而我们没有办法通过组件更新前条件来决定组件是否存在更新。而且在函数组件中,不再也。区分mount状语从句:update两个状态,这意味着函数组件的每一次调用都会执行内部的所有逻辑,就带来了非常大的性能损耗。useMemo状语从句:useCallback都是解决上述性能问题的。
React.memo() 是判断一个函数组件的渲染是否重复执行;
useMemo() 是定义一段函数逻辑是否重复执行;
useMemo(() => fn, inputs)跟useCallback(fn, inputs)效果一样。

import React, { useMemo } from 'react';

function UseMemo() {
    // useMemo 接收两个参数,一个是 callback,第二个参数是一个数组,与 useEffect 类似
    const increase = useMemo(() => {
        if (value > 2) return value + 1;
    }, [value]);
}

export default UseMemo;

useRef

  • 使用useRef获取React JSX中的DOM元素,获取后你就可以控制DOM的任何东西了。但是一般不建议这样来作,React接口的变化可以通过状态来控制。
  • 用useRef来保存变量,渲染周期之间共享数据的存储(状态不能存储跨渲染周期的数据,因为状态的保存会触发组件重渲染),不过这个功能不多用,因为有了useContext。

获取DOM报表

import React, { useEffect, useRef } from 'react';

function UseRef() {
    // 定义一个 ref
    const h1Ref = useRef();

    useEffect(() => {
        // 输出获取到的DOM节点
        console.log('useRef',h1Ref)
    }, [])

    return (
        <div>
            {/*保存 h1 的ref到 h1Ref */}
            <h1 ref={h1Ref}>Hello World!</h1>
        </div>
    )
}

export default UseRef;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值