美文网首页
自定义hook

自定义hook

作者: 未路过 | 来源:发表于2022-11-06 00:41 被阅读0次

多个组件有相同的逻辑的时候,可以把他抽取到一个独立的hook里面。
自定义hook的本质就是函数代码的抽取,他本身不算是react的特性。
自定义hook的要求是函数的名字必须以use开头

练习1

image.png
import React, { memo, useEffect, useState } from "react";

function useLogLife(cName) {
  useEffect(() => {
    console.log(cName + "组件被创建");
    return () => {
      console.log(cName + "组件被销毁");
    };
  }, []);
}
const Home = memo(() => {
  useLogLife("home");

  return <h1>Home Page</h1>;
});

const About = memo(() => {
  useLogLife("about");

  return <h1>About Page</h1>;
});
const App = memo(() => {
  const [isShow, setIsShow] = useState(true);

  useLogLife("app");
  return (
    <div>
      {isShow && <Home />}
      {isShow && <About />}
      <button onClick={(e) => setIsShow(!isShow)}>切换</button>
    </div>
  );
});

export default App;
/* 

home组件被创建
about组件被创建
app组件被创建
*/

练习2

image.png
import React, { memo } from 'react'
import { useUserToken } from "./hooks"

// User/Token

const Home = memo(() => {
  const [user, token] = useUserToken()

  return <h1>Home Page: {user.name}-{token}</h1>
})

const About = memo(() => {
  const [user, token] = useUserToken()

  return <h1>About Page: {user.name}-{token}</h1>
})

const App = memo(() => {
  return (
    <div>
      <h1>App Root Component</h1>
      <Home/>
      <About/>
    </div>
  )
})

export default App
import { useContext } from "react"
import { UserContext, TokenContext } from "../context"

function useUserToken() {
  const user = useContext(UserContext)
  const token = useContext(TokenContext)

  return [user, token]
}

export default useUserToken

练习3

监听窗口滚动

import { useState, useEffect } from "react";

function useScrollPosition() {
  const [scrollX, setScrollX] = useState(0);
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    function handleScroll() {
      // console.log(window.scrollX, window.scrollY)
      //window和document的区别是,window发生滚轮事件,会传递给document,所以document也会拿到,
      setScrollX(window.scrollX);
      setScrollY(window.scrollY);
    }

    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return [scrollX, scrollY];
}

export default useScrollPosition;

import React, { memo } from 'react'
import { useUserToken } from "./hooks"

// User/Token

const Home = memo(() => {
  const [user, token] = useUserToken()

  return <h1>Home Page: {user.name}-{token}</h1>
})

const About = memo(() => {
  const [user, token] = useUserToken()

  return <h1>About Page: {user.name}-{token}</h1>
})

const App = memo(() => {
  return (
    <div>
      <h1>App Root Component</h1>
      <Home/>
      <About/>
    </div>
  )
})

export default App

练习4

image.png
import { useEffect } from "react"
import { useState } from "react"

function useLocalStorage(key) {
  // 1.从localStorage中获取数据, 并且数据数据创建组件的state
  const [data, setData] = useState(() => {
    const item = localStorage.getItem(key)
    if (!item) return ""
    return JSON.parse(item)
  })

  // 2.监听data改变, 一旦发生改变就存储data最新值
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(data))
  }, [data])

  // 3.将data/setData的操作返回给组件, 让组件可以使用和修改值
  return [data, setData]
}


export default useLocalStorage
import React, { memo } from 'react'
import { useEffect } from 'react'
import { useState } from 'react'
import useLocalStorage from './hooks/useLocalStorage'

const App = memo(() => {
  // 通过key, 直接从localStorage中获取一个数据
  // const [token, setToken] = useState(localStorage.getItem("token"))
  // useEffect(() => {
  //   localStorage.setItem("token", token)
  // }, [token])
  const [token, setToken] = useLocalStorage("token")
  function setTokenHandle() {
    setToken("james")
  }

  // const [avatarUrl, setAvatarUrl] = useState(localStorage.getItem("avatarUrl"))
  // useEffect(() => {
  //   localStorage.setItem("avatarUrl", avatarUrl)
  // }, [avatarUrl])
  const [avatarUrl, setAvatarUrl] = useLocalStorage("avatarUrl")
  function setAvatarUrlHandle() {
    setAvatarUrl("http://www.james.com/cba.png")
  }

  return (
    <div className='app'>
      <h1>App Root Component: {token}</h1>
      <button onClick={setTokenHandle}>设置token</button>
      <h1>avatarURL: {avatarUrl}</h1>
      <button onClick={setAvatarUrlHandle}>设置新头像地址</button>
    </div>
  )
})

export default App

相关文章

  • 在React中创建自定义hook

    什么是自定义hook? 使用自定义hook可以将某些组件逻辑提取到可重用的函数中。 自定义hook是一个从use开...

  • react的一些总结

    什么时候自定义Hook? 当多个组件之间有一些公共的逻辑,可以将他们抽取成自定义的Hook,Hook本质是自定义的...

  • 自定义Hook & 高阶组件

    自定义Hook 自定义Hook: 将一些常用的、跨越多个组件的Hook功能,抽离出去形成一个函数,该函数就是自定义...

  • 自定义hook

    自定义hook 需求描述:自定义一个hook函数,实现获取滚动距离Y const [y] = useWindowS...

  • fishHook-代码实例

    可以HOOK系统的C函数,但无法HOOK自定义的函数 fishHook 无法交换自定义函数!!!,这个函数肯定是C...

  • DebugValue Hook

    DebugValue Hook useDebugValue:用于将自定义Hook的关联数据显示到调试栏 如果创建的...

  • [react]24、自定义hooks

    1、自定义Hook的基本使用 自定义Hook本质上只是一种函数代码逻辑的抽取,严格意义上来说,它本身并不算Reac...

  • Hook

    Hook 概念和特点 useState useRef EffectHook 自定义钩子 useCallback u...

  • 记一次git hook踩坑(python编写hook脚本)

    背景:项目内有个zip包需要发版时去网上更新,自定义一个pre-commit hook来解决。 hook逻辑编写(...

  • Vue3 Hooks 替代了 Vue2 Mixins

    前言 我们知道,React社区,已经全面拥抱Hook。Vue3的发布也支持了自定义Hook,作为只会Vue2的前端...

网友评论

      本文标题:自定义hook

      本文链接:https://www.haomeiwen.com/subject/zfaytdtx.html