@blocklet/ui-react
Version:
Some useful front-end web components that can be used in Blocklets.
214 lines (165 loc) • 8.03 kB
Markdown
# Hooks API
本节为库中可用的自定义 React Hooks 提供了详细参考。这些 hooks 旨在封装和复用有状态逻辑,从而简化 Blocklet 环境中的常见任务和交互。
## useComponentInstalled
此 hook 检查一个或多个指定的可选组件(通过其 DID 识别)是否已安装。它对于实现依赖其他 Blocklet 的功能至关重要。该 hook 提供安装状态和必要的 URL,以便在需要时提示用户进行安装。
### 参数
该 hook 接受一个包含以下属性的对象:
<x-field-group>
<x-field data-name="did" data-type="string | string[]" data-required="true">
<x-field-desc markdown>要检查的组件的去中心化标识符(DID)或 DID 数组。单个字符串可包含多个由 `;;` 分隔的 DID。</x-field-desc>
</x-field>
<x-field data-name="onInstalled" data-type="function" data-required="false">
<x-field-desc markdown>一个可选的回调函数,当所有指定组件都已安装时触发。</x-field-desc>
</x-field>
<x-field data-name="onError" data-type="function" data-required="false">
<x-field-desc markdown>一个可选的回调函数,当一个或多个指定组件未安装时触发。</x-field-desc>
</x-field>
</x-field-group>
### 返回值
它返回一个包含安装状态和相关数据的对象:
<x-field-group>
<x-field data-name="optComponents" data-type="array">
<x-field-desc markdown>一个包含未安装组件对象的数组。每个对象都包含元数据,如 `meta.did`、`storeUrl` 和 `installUrl`。</x-field-desc>
</x-field>
<x-field data-name="installed" data-type="boolean">
<x-field-desc markdown>一个布尔值,如果所有指定组件都已安装并在 `blocklet.yml` 中定义,则为 `true`,否则为 `false`。</x-field-desc>
</x-field>
<x-field data-name="installStatus" data-type="object">
<x-field-desc markdown>一个对象,其中键是组件的 DID,值是其当前的安装状态(例如,'waiting'、'installing')。此状态通过 `window.postMessage` 事件更新。</x-field-desc>
</x-field>
<x-field data-name="setInstallStatus" data-type="function">
<x-field-desc markdown>用于手动更新 `installStatus` 对象的状态设置函数。</x-field-desc>
</x-field>
<x-field data-name="definedInBlockletYML" data-type="boolean">
<x-field-desc markdown>一个布尔值,指示组件是否在 blocklet 的配置(`blocklet.yml`)中定义。</x-field-desc>
</x-field>
</x-field-group>
### 示例用法
以下示例演示了如何在缺少依赖项时,使用 `useComponentInstalled` 来条件性地渲染一个功能或一个 `ComponentInstaller` 组件。
```javascript "ComponentFeature.js" icon=logos:javascript
import React from 'react';
import { useComponentInstalled, ComponentInstaller } from '@blocklet/ui-react';
const REQUIRED_DID = 'z8ia24z55nve2TSF5m1aZ5322d9f48a43D4a'; // 示例 DID
function ComponentFeature() {
const { installed, optComponents } = useComponentInstalled({ did: REQUIRED_DID });
if (!installed) {
// 如果组件不存在,则渲染安装器界面
return <ComponentInstaller components={optComponents} />;
}
// 渲染依赖于已安装组件的功能
return (
<div>
<h2>My Feature</h2>
<p>This feature requires the component with DID: {REQUIRED_DID}</p>
{/* ... 功能实现 ... */}
</div>
);
}
export default ComponentFeature;
```
## useFollow
此 hook 管理当前认证用户与另一位由其 DID 指定的用户之间的关注关系。它处理关注和取消关注的 API 调用,并提供当前的关注状态。
### 参数
<x-field-group>
<x-field data-name="userDid" data-type="string" data-required="true">
<x-field-desc markdown>要检查关注状态的用户配置文件的 DID。</x-field-desc>
</x-field>
<x-field data-name="t" data-type="function" data-required="true">
<x-field-desc markdown>用于显示成功或错误消息的翻译函数(例如,来自 `react-i18next`)。</x-field-desc>
</x-field>
<x-field data-name="isMySelf" data-type="boolean" data-required="true">
<x-field-desc markdown>一个布尔值,如果 `userDid` 属于当前登录的用户,则应设置为 `true`。</x-field-desc>
</x-field>
</x-field-group>
### 返回值
返回一个包含以下属性的对象:
<x-field-group>
<x-field data-name="followed" data-type="boolean">
<x-field-desc markdown>指示当前用户是否正在关注由 `userDid` 指定的用户。如果正在关注,则为 `true`,否则为 `false`。</x-field-desc>
</x-field>
<x-field data-name="followUser" data-type="function">
<x-field-desc markdown>一个稳定的函数,用于调用以关注用户。它处理 API 请求并在成功后更新 `followed` 状态。</x-field-desc>
</x-field>
<x-field data-name="unfollowUser" data-type="function">
<x-field-desc markdown>一个稳定的函数,用于调用以取消关注用户。它处理 API 请求并在成功后更新 `followed` 状态。</x-field-desc>
</x-field>
</x-field-group>
### 示例用法
此示例展示了如何创建一个 `FollowButton` 组件,该组件根据关系状态显示“关注”或“取消关注”操作。
```javascript "FollowButton.js" icon=logos:javascript
import React from 'react';
import Button from '@mui/material/Button';
import { useTranslation } from 'react-i18next';
import { useFollow } from '@blocklet/ui-react/hooks';
import { useSession } from '@blocklet/did-connect-react';
function FollowButton({ profileDid }) {
const { session } = useSession();
const { t } = useTranslation();
const isMySelf = session?.user?.did === profileDid;
const { followed, followUser, unfollowUser } = useFollow({
userDid: profileDid,
t,
isMySelf,
});
if (isMySelf) {
return null; // 不在自己的个人资料页显示按钮
}
const handleClick = () => {
if (followed) {
unfollowUser();
} else {
followUser();
}
};
return (
<Button variant="contained" onClick={handleClick}>
{followed ? t('profile.unfollow') : t('profile.follow')}
</Button>
);
}
export default FollowButton;
```
## useMobile
一个用于创建响应式组件的简单实用工具 hook。它利用 Material-UI 的 `useMediaQuery` 来确定当前视口宽度是否低于指定的断点。
### 参数
<x-field-group>
<x-field data-name="key" data-type="number | Breakpoint" data-default="'sm'" data-required="false">
<x-field-desc markdown>Material-UI 断点键(例如,`'xs'`、`'sm'`、`'md'`)或用于比较的像素值。如果屏幕宽度小于此值,该 hook 返回 `true`。</x-field-desc>
</x-field>
</x-field-group>
### 返回值
返回一个 `boolean` 值:如果视口小于指定的断点,则为 `true`,否则为 `false`。
### 示例用法
此 hook 必须在由 Material-UI `ThemeProvider` 包裹的组件树中使用。
```javascript "ResponsiveComponent.js" icon=logos:javascript
import React from 'react';
import Typography from '@mui/material/Typography';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { useMobile } from '@blocklet/ui-react/hooks';
// 一个使用该 hook 的组件
function ResponsiveComponent() {
const isMobile = useMobile({ key: 'md' }); // 根据 'md' 断点进行检查
return (
<div>
{isMobile ? (
<Typography variant="h6">Mobile View</Typography>
) : (
<Typography variant="h4">Desktop View</Typography>
)}
<p>Resize your browser window to see the content change.</p>
</div>
);
}
// 该组件必须被包裹在 ThemeProvider 中
const theme = createTheme();
function App() {
return (
<ThemeProvider theme={theme}>
<ResponsiveComponent />
</ThemeProvider>
);
}
export default App;
```
---
通过使用这些 hooks,您可以用最少的样板代码高效地实现复杂功能。有关可能使用这些 hooks 的组件的更多信息,请参阅 [组件](./components.md) 文档。