# @brightleaf/react-hooks 中文文档

规范地址：https://npmcn.com/package/%40brightleaf/react-hooks/

版本：5\.1\.1
npm 元数据更新时间：2022-07-20T05:26:05.135Z
中文译文更新时间：2026-11-08T15:20:43.657Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40brightleaf/react-hooks
原文对照：https://npmcn.com/package/%40brightleaf/react-hooks/?lang=original
项目主页：https://brightleaf.dev/hooks
源码仓库：https://github.com/brightleaf/react-hooks

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：75.1 kB，41 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- 运行依赖：1 个
- peer 依赖：react 16\.x \|\| 17\.x \|\| 18\.x，graphql-request \*
- 首次发布：2019-05-08T05:13:17.098Z
- 最新版本发布：2022-07-20T05:26:05.007Z
- 近 30 天下载量：28293（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：44（近 12 个月 0 个）

## 中文简介

有用的反应钩

## 安装

```sh
npm install @brightleaf/react-hooks
```

也可以使用：`pnpm add @brightleaf/react-hooks`、`yarn add @brightleaf/react-hooks`、`bun add @brightleaf/react-hooks`

## README

# 亮叶反应钩

有用反应钩

-   [`useAsync`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-async-hook) - 钩到主动函数
-   [`useFetch`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-fetch-hook) - 用钩来取取
-   [`useForm`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-form-hook) - 钩子可以很容易地使用表格
-   [`useGet`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-get-hook) - 虎克来请求
-   [`usePost`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-post-hook) - 钩来做个HTTP邮站
-   [`useClickOutside`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-click-outside-hook) - 钩来处理元素外的点击
-   [`useGraphQL`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-graphql-hook) - 胡克来提出GraphQL请求
-   [`useKeypress`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-keypress-hook) - 钩到按键
-   [`useKeypressed`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-key-pressed-hook) - 启动键盘时用钩子点出一个方法
-   [`useNes`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-/examples/nes) - 钩子连接到Hapijs NES
-   [`useWebSockets`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-/examples/ws) - 钩与 WebSockets 互动
-   [`useLocalStorage`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-local-storage-hook) - 钩到本地仓库
-   [`useCookie`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-cookie-hook) - 钩到饼干
-   [`useHover`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-hover-hook) - 钩来绑住一个元素
-   [`useEventListener`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-event-hook) - 用钩子绑住发件人到DOM事件
-   [`useFavicon`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-favicon-hook) - 钩子来摆出法维森
-   [`useTitle`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-title-hook) - 操纵页面标题的钩子
-   [`useMetaTag`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-meta-tag-hook) - 操纵元标记的钩子
-   [`useScript`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-script-hook) 将 JavaScript 添加到页面
-   [`useStyles`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-style-hook) - 钩子在页面上添加 CSS
-   [`useStyleSheet`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-stylesheet-hook) - 钩子在页面上添加一个 css 文件
-   [`usePageVisibility`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-pagevisibility-hook) - 钩子使用页面能见度 api
-   [`useOnlineStatus`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-onlinestatus-hook) - 钩子使用在线状态 api
-   [`useMediaQuery`](https://npmcn.com/package/%40brightleaf/react-hooks/#readme-media-query-hook) - 如果媒体查询匹配, 回钩

[实例](https://brightleaf.dev/hooks/examples/#/)

## 自动钩

```jsx
import React, { useEffect } from 'react'
import { useAsync } from '@brightleaf/react-hooks'

export default () => {
  const { loading, error, data, execute } = useAsync(asyncFunction)
  useEffect(() => {
    execute()
  }, [])
  if (loading) {
    return <div>Executing Async Function</div>
  }
  if (error) {
    return <div>Error executing async function</div>
  }
  return <div>{data}</div>
}
```

## 获取钩

```javascript
import React, { useState } from 'react'
import { useFetch } from '@brightleaf/react-hooks'
export default () => {
  const [id, setId] = useState(1)

  const { data, error, loading } = useFetch(
    `https://swapiql.herokuapp.com/api/characters/${id}`
  )
  if (error) {
    return (
      <div className="App">
        <h1>Error Getting Data</h1>
      </div>
    )
  }
  if (loading) {
    return (
      <div className="App">
        <h1>Loading Data</h1>
      </div>
    )
  }
  return (
    <div className="App">
      <h1>{data[0].name}</h1>
    </div>
  )
}
```

## 窗体钩

```javascript
import React, { useState } from 'react'
import { useForm } from '@brightleaf/react-hooks'
export default () => {
  const { addToForm, onSubmit } = useFetch()
 
  return (
    <form
        onSubmit={onSubmit(data => {
          console.info('onsubmit handler', data)
        })}
      >
        <fieldset>
          <legend>Form Hook</legend>
          <input
            name="firstName"
            type="text"
            ref={addToForm}
            defaultValue="Brightleaf"
          />
          <input
            name="lastName"
            type="text"
            ref={addToForm}
            defaultValue="Hooks"
          />
          <br />
          <select ref={addToForm} name="dropdown" defaultValue="13">
            <optgroup label="First Group">
              <option value="1">First</option>
              <option value="2">Second</option>
              <option value="3">Third</option>
            </optgroup>
            <optgroup label="Second Group">
              <option value="11">Second First</option>
              <option value="12">Second Second</option>
              <option value="13">Second Third</option>
            </optgroup>
          </select>
          <br />
          <input type="checkbox" name="check" defaultChecked ref={addToForm} />
          <br />
          <div>
            <label>The Radio</label>
            <div>
              <label> First </label>
              <input name="rgroup" type="radio" value="first" ref={addToForm} />
            </div>
            <div>
              <label> Second </label>
              <input
                name="rgroup"
                type="radio"
                value="second"
                ref={addToForm}
              />
            </div>
          </div>
          <br />
          <button type="submit">Submit</button>
        </fieldset>
      </form>
  )
}
```

## 图QL 钩

```javascript
import React, { useState } from 'react'
import { useGraphQL } from '@brightleaf/react-hooks'

export default () => {
  const [id, setId] = useState(1)
  const { data, loading, error } = useGraphQL(
    'https://swapiql.herokuapp.com/graphql',
    `query Person($id: ID) {
      person(id: $id) {
        id,
        name
      }
    }`,
    { id }
  )
  if (loading) {
    return <div>Loading Data</div>
  }
  if (error) {
    return <div>Error getting graphql data</div>
  }
  return <div>{data.person[0].name}</div>
}
```

## 按键钩

```jsx
import React from 'react'
import { useKeypress } from '@brightleaf/react-hooks'
export default () => {
  const aKeyDown = useKeypress('a')
  return (
    <div className="App content">
      <h2>Key Press?</h2>
      {aKeyDown && (
        <div>
          Yes, the <b>{'"a"'}</b> key is pressed
        </div>
      )}
      {!keyDown && <div>No the <b>{'"a"'}</b> key is not currently pressed</div>}
    </div>
  )
}
```

## 按键钩

```jsx
import React, { useState } from 'react'
import { useKeypressed } from '@brightleaf/react-hooks'
export default () => {

  const keyPressed = useKeypressed('a')

  return (
    <div className="App content">
      <h2>Key Press?</h2>
      {keyPressed && (
        <div>
          Yes, the <b>{'"a"'}</b> key has been pressed
        </div>
      )}
      {!keyPressed && <div>No the <b>{'"a"'}</b> key is not been pressed yet</div>}
    </div>
  )
}
```

## 后钩

```javascript
import React from 'react'
import { Button, Form, TextBox } from 'react-form-elements'
import { usePost } from '@brightleaf/react-hooks'

export default () => {
  const { data, error, loading, postData } = usePost(
    `https://kev-pi.herokuapp.com/api/echo`
  )

  if (loading) {
    return <div>Loading Data</div>
  }
  if (error) {
    return <div>Error getting graphql data</div>
  }
  return (
    <Form
      name="testForm"
      onSubmit={data => {
        postData(data)
      }}
    >
      <TextBox label="My Label" name="myTextBox" />
      <Button>Send</Button>
    </Form>
  )
}

```

## 找虎克来

```javascript
import React, { useState } from 'react'
import { useGet } from '@brightleaf/react-hooks'
export default () => {
  const [id, setId] = useState(1)

  const { data, error, loading, getUrl } = useGet(
    `https://swapiql.herokuapp.com/api/characters/${id}`
  )
  if (error) {
    return (
      <div className="App">
        <h1>Error Getting Data</h1>
      </div>
    )
  }
  if (loading) {
    return (
      <div className="App">
        <h1>Loading Data</h1>
      </div>
    )
  }
  return (
    <div className="App">
      <h1>{data[0].name}</h1>
      <h2>Pick a number</h2>
      <div className="select">
        <div
          onClick={e => {
            getUrl('https://swapiql.herokuapp.com/api/characters/2')
          }}
        >
          2
        </div>
      </div>
    </div>
  )
}
```

## 点击外钩

```javascript
import React, { useState, useRef } from 'react'
import { useClickOutside } from '@brightleaf/react-hooks'

export default () => {
  const [menu, setMenu] = useState(false)
  const navMenu= useRef()
  const hideDropDown = () => {
    setMenu(false)
  }
  useClickOutside(navMenu, hideDropDowns, menu)

  return (
    <div className="App">
      <nav ref={navMenu}>
        <div className={`dropdown ${menu ? 'active' : ' '}`}>
          <button
            type="button"
            className="dropdown-trigger"
            onClick={e => {
              setMenu(!menu)
            }}
          >
            Menu
          </button>
          <div>
            ...// items
          </div>
        </div>
      </nav>
      ... // rest of page
    </div>
  )
}
```

## 标题钩

```jsx
import React, { useEffect } from 'react'
import { useTitle } from '@brightleaf/react-hooks'

export default () => {
  useTitle('Brightleaf JS Hooks')

  return <div>The Page</div>
}
```

## 元标记钩

```jsx
import React, { useEffect } from 'react'
import { useMetaTag } from '@brightleaf/react-hooks'

export default () => {
  const [metaValue, setMetaValue] = useMetaTag('description', 'Brightleaf JS React Hooks')
  // <meta name="description" content="Brightleaf JS React Hooks">
  setMetaValue('Awesome React Hooks from Brightleaf JS')
  // <meta name="description" content="Awesome React Hooks from Brightleaf JS">
  useMetaTag(
    'og:title',
    'Brightleaf JS React Hooks',
    'property'
  )
  // <meta property="og:title" content="Brightleaf JS React Hooks">
  return <div>The Page</div>
}
```

# NES 钩

连接到 an 的客户端钩钩 [无](https://github.com/hapijs/nes) 实例

# WebSocket 虎克

#/实例/ws

### 信件

```javascript
import React from 'react'
import { useNes } from '@brightleaf/react-hooks'
export default () => {

  const { messages, error, connecting, connected } = useNes(
    'wss://kev-pi.herokuapp.com'
  )

  if (error) {
    return <div><h1>Error</h1></div>
  }
  const connectMessage = connecting ? <div>Connecting</div> : <div>Not Connecting</div>
  const connectedMessage = connected ? <div>Connected</div> : <div>Not Connected</div>

  const messageList = messages.map((m, index) => <div key={`key-${index}`}>{m}</div>)
  return (
    <div className="App">
      <h1>Messages from Server</h1>
      <div>{messageList}</div>
      <div>
        <b>Status Messages</b>
        {connectMessage}
        {connectedMessage}
      </div>
    </div>
  )
}

```

### 订阅

使用钩子上的客户端创建实时聊天室

```javascript
import React, { useState}  from 'react'
import { useNes } from '@brightleaf/react-hooks'
export default () => {
  const { client } = useNes('wss://kev-pi.herokuapp.com')
  const [messages, setMessages] = useState([{
    body: 'welcome',
    user: 'system'
  }])
  const addMessage = (msg) =>  {
    messages.push(msg)
    setMessages([...messages])
  }
  const handler = function(update, flags) {
    addMessage(update)
  }
  // subscribe to a channel
  client.subscribe('/rooms/general', handler);

  const messageList = messages.map(({user, body}, index) => (<div key={`key-${index}`}><b>{user}:</b>{body}</div>))
  return (
    <div>
      {messageList}
    </div>
  )
}
```

## 本地存储钩

```javascript
import React, { useRef } from 'react'
import { useLocalStorage } from '@brightleaf/react-hooks'

export default () => {
  const [count, setCount] = useLocalStorage('count', 0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

## 饼干虎克

```javascript
import React, { useRef } from 'react'
import { useCookie } from '@brightleaf/react-hooks'

export default () => {
  const [count, setCount] = useCookie('count', 0);
  const [longCount, setLongCount] = useCookie('count', 0, { expires: 21 });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

## 猎钩

```javascript
import React, { useRef } from 'react'
import { useHover } from '@brightleaf/react-hooks'

export default () => {
  const elRef = useRef(null);
  const hovered = useHover(elRef);

  return (
    <div>
      <div className={ hovered ? 'animated' : 'static' }>
        Hover Over Me
      </div>
    </div>
  );
}
```

## 样式钩

```javascript
import React from 'react'
import { useStyles } from '@brightleaf/react-hooks'

export default () => {
   useStyles(`
    html,
    body {
        font-family: 'Open Sans';
    }
    div {
        padding: 5px;
        border: 1px solid #ccc;
    }
  `)

  return (
    <div>
      <div>
        Something
      </div>
    </div>
  );
}
```

## 样式滑轮钩

```javascript
import React from 'react'
import { useStyleSheet } from '@brightleaf/react-hooks'

export default () => {
  useStyleSheet(
    'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'
  )
  useStyleSheet('https://fonts.googleapis.com/css?family=Open+Sans')

  return (
    <div>
      ...
    </div>
  );
}
```

## 脚本钩

```javascript
import React from 'react'
import { useScript } from '@brightleaf/react-hooks'

export default () => {
  useScript('/js/script.js')

  return (
    <div>
      ...
    </div>
  );
}
```

## 页面可视性钩

```javascript
import React from 'react'
import { usePageVisibility } from '@brightleaf/react-hooks'

export default () => {
  const { visible, hidden } = usePageVisibility()

  return (
    <div>
      ...
    </div>
  );
}
```

## 法维康虎克

```javascript
import React from 'react'
import { useFavicon } from '@brightleaf/react-hooks'

export default () => {

  const { favicon, setFavicon } = useFavicon('brightleaf.png')

  return (
    <div>
      <button onClick={e => {
        e.preventDefault()
        setFavicon('brightleaf-1.png')
      }}>Change Favicon</button>
    </div>
  );
}
```

## 在线状态钩

```javascript
import React from 'react'
import { useOnlineStatus } from '@brightleaf/react-hooks'

export default () => {
  const { offline, online } = useOnlineStatus()
  return (
    <div>
      <h3>
        {offline && 'Connection is offline'}
        {online && 'Connection is online'}
      </h3>
      {offline && (
        <article className="message is-danger">
          <div className="message-body">Connection is offline </div>
        </article>
      )}
      {online && (
        <article className="message is-success">
          <div className="message-body">Connection is online </div>
        </article>
      )}
    </div>
  )
}
```

## 事件钩

```javascript
import React , { useState } from 'react'
import { useEventListener } from '@brightleaf/react-hooks'

export default () => {
  const [state, setState] = useState(window.scrollY)
  const onScroll = e => {
    setState(window.scrollY)
  }
  useEventListener('scroll', onScroll)
  return (
    <div className="App content">
      <h2>Scroll the page</h2>
      <span
        style={{
          position: 'fixed',
          top: 10,
          left: 10,
          background: '#CCCCCC',
        }}
      >
        {state} scroll position
      </span>
      <Home></Home>
    </div>
  )
}
```

## 媒体查询钩

```javascript
import React , { useState } from 'react'
import { useMediaQuery } from '@brightleaf/react-hooks'

export default () => {

  const { matches } = useMediaQuery('(min-width: 500px)')
  return (
    <div className="App content">
      {matches && (
        <article className="message is-warning">
          <div className="message-body">The page is at least 500px</div>
        </article>
      )}
    </div>
  )
}
```

## 常见问题

### @brightleaf/react-hooks 是什么？

有用的反应钩

### 如何安装 @brightleaf/react-hooks？

在项目目录运行 npm install @brightleaf/react-hooks，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（16\.x \|\| 17\.x \|\| 18\.x）、graphql-request（\*）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @brightleaf/react-hooks 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/brightleaf\_\_react-hooks 是否存在。

### @brightleaf/react-hooks 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @brightleaf/react-hooks 可以商用吗？

@brightleaf/react-hooks 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @brightleaf/react-hooks 的下载量有多少？

根据 npm 官方下载统计，@brightleaf/react-hooks 在 2026/10/09 – 2026/11/07 这 30 天内被下载 28,293 次，日均约 943 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @brightleaf/react-hooks 还在维护吗？

最新版本 5\.1\.1 发布于 2022/07/20（4 年前）；至今共发布 44 个版本，其中过去 12 个月发布了 0 个；首次发布于 2019/05/08。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

