React 学习(四)

React Hooks

高阶组件为了复用,导致代码层级复杂

生命周期复杂

函数式组件,无状态组件=》又需要状态==》改成class成本高

React Hooks提供了一种在函数组件中使用状态(state)和其他 React 特性的方式,以取代传统的基于类的组件。

Hooks 只能在函数组件的顶层作用域中调用,不能在循环、条件语句或嵌套函数中使用。这是因为 React 需要根据 Hooks 的调用顺序来跟踪组件的状态和更新。

Hooks中没有this

useState

useState 保存组件状态 , setXxx会将整个函数组件重新执行

import React, { useState } from 'react'
export function App(){
  const [ name, setname ] = useState('')
  return(
  	<div>
    	{
        console.log('name' ,name)
      }
      <button onClick={()=>{
        setname('小明')
      }}>点击</button>
    </div>
  )
}
/*
	> name
	---点击之后--
	> name 小明
*/

useEffect 处理副作用

useEffect(()=>{
  //其中逻辑立即执行一次
  //如果在第二参数传递相应状态,改变时,会再次执行这个副作用回调(有点类似Vue的watch)
  return ()=>{
    // 销毁逻辑
	}
},[])
//依赖的数组。空数组表示不依赖  

可多次使用

useLayoutEffect

useLayoutEffect 和原来DidMount DidUpdat一致,在react完成DOM更新后马上同步调用代码

useEffect在整个页面渲染完才会调用(不会阻塞页面渲染)

假如要在Effect中进行DOM操作,最好使用LayoutEffect,避免页面抖动,只有一次回流重绘的代价

useCallback()

useState 可以记住状态

useCallback is a React Hook that lets you cache a function definition between re-renders.

useCallback() 缓存函数

组件更新会导致组件内函数也相应更新。但是如果使用useCallback只在所依赖值改变后,再进行更新。

跟dependecies不相关的元素改变,不会导致这个记忆函数重新执行

import React, { useState, useCallback } from 'react'
export function App(){
  const [ name, setname ] = useState('')
  const fn = useCallback(()=>{
    console.log('name1' ,name)
  }, []) // 没有设置name依赖数据,记忆函数记忆第一次状态,不会更改回调里的数据
  const fn2 = () => {
    console.log('name2', name)
  }
  return(
  	<div>
       { /* 点击按钮 */ }
    	{
        fn() // 怎么输出都为空
      }
      {
        fn2() // 输出name属性
      }
      <button onClick={()=>{
        setname('小明')
      }}>点击</button>
    </div>
  )
}

useMemo

useMemo 记忆组件(类似vue计算属性)

useMemo is a React Hook that lets you cache the result of a calculation between re-renders.

会执行回调函数,并将回调的执行结果返回回来

import React, { useState, useMemo } from "react";

function getList(val?: number){
  const arr =  [1, 2, 3, 4]
  if(val){
    arr.push(val)
  }
  return arr
}
export default function APP() {
  const [count, setcount] = useState(0);
  const res = useMemo(()=> getList(count), [count]) //自动根据依赖计算属性
  return (
    <div>
      <strong>{res}</strong>
      <button onClick={() => {
          setcount(2)
        }}
      >
        点击
      </button>
    </div>
  );
}

useRef()

useRef() 类似class 的createRef

如何保存临时变量(闭包):useState,useRef引用唯一变量

const myref = useRef()

...
<input ref={myref} />
...
{
 myref.current
}

useContext

useContext减少组件层级

上下文(Context)是 React 中一种跨组件层级共享数据的机制。通过上下文,可以避免通过组件层层传递 props 的方式来共享数据,使得组件之间的通信更加简洁和灵活。

import React, { useState, useContext } from "react";

const GlobalContext = React.createContext({} as any); //初始化传递一个空对象

function Child() {
  // useContext 相当于之前的Consumer
  const value = useContext(GlobalContext);
  return (
    <div>
      <button
        onClick={() => {
          value.changeInfo("哈哈");
          console.log("?", value.info);
        }}
      >
        改变info
      </button>
    </div>
  );
}

export default function APP() {
  const [info, setinfo] = useState("一段初始化信息");
  return (
    <GlobalContext.Provider
      value={{
        info,
        changeInfo: (val: any) => {
          setinfo(val);
        }
      }}
    >
      <Child />
    </GlobalContext.Provider>
  );
}

useReducer

useReducer (Redux)

外部管理集中状态 (类似vuex)

每次创建的reducer实例不是共享的

只能在hook中调用

配合useContext跨级通信实现状态共享

import React, { useContext, useReducer } from "react";

const GlobalContext = React.createContext({} as any); //初始化传递一个空对象

// 初始化共享状态
const initalState = {
  info: "初始化文字"
};
// 分发逻辑
const reducer = (state: any, action: any) => {
  const newState = { ...state }; //拷贝老状态
  switch (action.type) {
    case 1:
      newState.info = action.value; //修改状态
      return newState; //返回一个新的状态
  }
};

export default function APP() {
  const [state, dispatch] = useReducer(reducer, initalState);
  return (
    <GlobalContext.Provider
      value={{
        state,
        dispatch
      }}
    >
      <Child />
    </GlobalContext.Provider>
  );
}

function Child() {
  // useContext 相当于之前的Consumer
  const { state, dispatch } = useContext(GlobalContext);
  return (
    <div>
      <button
        onClick={() => {
          dispatch({
            type: 1,
            value: "新的Info"
          });
        }}
      >
        改变info
      </button>

      <strong>{state.info}</strong>
    </div>
  );
}

视图逻辑与状态逻辑分离

自定义Hooks

两个函数共享逻辑时,我们会把他提取到第三个函数中

命名use开头,这样React会自动进行检查

(只是抽离逻辑,为了复用逻辑)

import React from "react";

// 模拟列表
function getList(val?: number){
  const arr = [1, 2, 3]
  if(val){
    arr.push(val)
  }
  return arr
}

// 获取列表自定义Hooks
const useList = (val?: number) => {
  return getList(val)
}
export default function APP() {
  const list = useList(1)
  return (
    <div>
      <ul>
        {
          list.map(item=><li key={item}> {item} </li>)
        }
      </ul>
    </div>
  )
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值