zl程序教程

您现在的位置是:首页 >  其他

当前栏目

React Hook案例集锦

2023-04-18 13:13:24 时间

React Hook本质就是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 hook,结果一般会有返回值,使用hook的目的一般是抽离多个组件的公共逻辑,本文以6个案例来带大家熟悉React Hook的使用。

首先看第一个案例,一个简单的Hook函数,啥也没做,只是带大家熟悉一下hook的定义形式:

import { useState } from 'react'

const useMyHook = (initValue) => {
  const [value, setValue] = useState(initValue || '')
  return value
}

function App() {
  const myHookValue = useMyHook('myHook')
  return <div className="app">{myHookValue}</div>
}

上述代码中,我们就可以看出,我自定义了一个名为useMyHook的自定义hook,而它也并没有什么功能,只是用来返回一个自定义的值。

第二个案例,我们来对上面的案例进行升级,加入一个 input,来让你更清楚的认识到 自定义 hook。我们现在需要有一个输入框,并通过一个自定义 hook ,来对它进行值的传递和函数值的修改:

import { useState } from 'react'

const useMyHook = (initValue) => {
  const [value, setValue] = useState(initValue || '')
  const onChange = (e) => {
    setValue(e.target.value)
  }
  return { value, onChange }
}

function App() {
  const myHookValue = useMyHook('myHook')
  return (
    <div className="app">
      <p>value:{myHookValue.value}</p>
      <input value={myHookValue.value} onChange={myHookValue.onChange} />
    </div>
  )
}

上面的代码中,我们建了一个可以通过输入框输入内容实时更改数据的案例。 通过一个 自定义 hook useMyHook 来实现,在这里,我们在 自定义 hook 中返回一个 value ,用来展示现在的值。一个 onChange 函数,用来修改当前的 value。而我们在使用时,p 标签中展示的是现在 value,input 的改变函数使用的是自定义中的 onChange,展示值时 myHookValue 中的 value。

第三个案例:假设我们的组件中有一个功能可以检索窗口的宽度。我们想知道用户何时调整屏幕大小。不使用hook,我们可以这样写:

const LayoutComponent = () => {
  const [onSmallScreen, setOnSmallScreen] = useState(false);

  useEffect(() => {
    checkScreenSize();
    window.addEventListener("resize", checkScreenSize);
  }, []);

  let checkScreenSize = () => {
    setOnSmallScreen(window.innerWidth < 768);
  };

  return (
    <div className={`${onSmallScreen ? "small" : "large"}`}>
      <h1>Hello World!</h1>
    </div>
  );
};

我们这里有一个具有onSmallScreen state的组件,该组件知道我们是否在宽度小于768像素的窗口中。要知道这一点,我们使用了useEffecthook。在该hook内,我们首先调用checkScreenSize函数,该函数更新onSmallScreen状态变量。最后,我们将checkScreenSize函数绑定到调整大小事件侦听器,以在发生调整大小事件时在必要时更新状态。

接下来我们将其中获取页面宽度的代码抽离出来构造一个hook:

import { useState, useEffect } from "react";

const useWindowsWidth = () => {
  const [isScreenSmall, setIsScreenSmall] = useState(false);

  let checkScreenSize = () => {
    setIsScreenSmall(window.innerWidth < 600);
  };
  useEffect(() => {
    checkScreenSize();
    window.addEventListener("resize", checkScreenSize);

    return () => window.removeEventListener("resize", checkScreenSize);
  }, []);

  return isScreenSmall;
};

export default useWindowsWidth;

然后我们在需要获取页面宽度的地方调用它:

import React from 'react'
import useWindowWidth from './useWindowWidth.js'

const MyComponent = () => {
  const onSmallScreen = useWindowWidth();

  return (
    // Return some elements
  )
}

第四个案例,我们可以将llocalStorage的存储抽离出来:

import React,{ useState, useEffect } from 'react'

export default function useLocalstoagehook(key) {

  const [name, setName] = useState(() => {
    const name = JSON.parse(localStorage.getItem(key))
    return name
  })

  useEffect(() => {
    // localStorage.setItem('name', name)
    localStorage.setItem(key, JSON.stringify(name))
  }, [name])
   
  return [name,setName]

}

在需要的地方调用:

import React, { useState, useEffect } from 'react'

import useLocalstoagehook from '../hook/localstoagehook'

export default function CustomLocalStorage() {
  
  const [name,setName]= useLocalstoagehook('name')

  return (
    <div>
      {name}
      <button onClick={e => setName('lsh')}>设置</button>
    </div>
  )
}

第五个案例,例如,假设您有一些组件可显示文章的评论列表。我们可以想象其中的几行:


const ArticleWithComments = (articleId) => {
  const [comments, setComments] = useState([])
  const [error, setError] = useState(null)

  let handleCommentsSuccessFetch = (articleComments) => setComments(articleComments)

  let handleError = error => setError(error)

  useEffect(() => {
    fetchComments(articleId, handleCommentsSuccessFetch, handleError)
  }, [])

  return (
    // Do something in the DOM
  )
}

const BlogPostWithComments = (blogPostId) => {
  const [comments, setComments] = useState([])
  const [error, setError] = useState(null)

  let handleCommentsSuccessFetch = (blogPostComments) => setComments(blogPostComments)

  let handleError = error => setError(error)

  useEffect(() => {
    fetchComments(blogPostId, handleCommentsSuccessFetch, handleError)
  }, [])

  return (
    // Do something in the DOM
  )
}

在这个例子中,我们有两个组成部分。他们俩都根据ID(文章ID或博客文章ID)获取评论列表。在useEffect hook中,我们有一个API调用,可通过两个函数检索这些注释。一个在成功的情况下将状态设置为注释,第二个在错误的情况下将状态设置为错误。 但是,功能在这两个组件之间是重复的。幸运的是,我们可以在自定义hook中提取此功能:

const useCommentsRetriever = (entityId) => {
  const [comments, setComments] = useState([]);
  const [error, setError] = useState(null);

  let handleCommentsSuccessFetch = (comments) => setComments(comments);

  let handleError = (error) => setError(error);

  useEffect(() => {
    fetchComments(entityId, handleCommentsSuccessFetch, handleError);
  }, []);

  return [comments, error];
};

在这里,我们有了hook useCommentsRetriever。它以一个entityId作为参数。这将是我们文章的ID或博客文章的ID。然后,它类似于组件中的内容。不同之处在于此自定义hook需要返回某些内容。我选择在这里返回一个数组。第一个元素是注释,第二个元素是错误。 它将以这种方式使用:

//Import the custom hook
import useCommentsRetriever from './useCommentsRetriever.js'

const ArticleWithComments = (articleId) => {

  const [comments, error] = useCommentsRetriever(articleId)

  return (
    // Do something in the DOM
  )
}

const BlogPostWithComments = (blogPostId) => {

  const [comments, error] = useCommentsRetriever(blogPostId)

  return (
    // Do something in the DOM
  )
}

看看我们需要写多少代码?该useCommentsRetriever一个id作为参数。这[comments, error]就是我们所谓的数组解构。hookuseCommentsRetriever返回一个数组。我们将该数组的第一项分配给变量名注释,将该数组的第二项分配给变量名错误。

以上便是react hook案例集锦希望对你有所帮助。