# @exytab/react-sortable-tree 中文文档

规范地址：https://npmcn.com/package/%40exytab/react-sortable-tree/

版本：0\.7\.0
npm 元数据更新时间：2025-01-12T14:00:19.819Z
中文译文更新时间：2026-11-14T06:24:35.345Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：1.3 MB，40 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18
- 运行依赖：6 个
- peer 依赖：react ^17\.0\.0 \|\| ^18\.0\.0 \|\| ^19\.0\.0，react-dnd 16\.0\.1，react-dom ^17\.0\.0 \|\| ^18\.0\.0 \|\| ^19\.0\.0
- 首次发布：2023-06-27T08:22:54.094Z
- 最新版本发布：2025-01-12T14:00:19.634Z
- 近 30 天下载量：2931（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：8（近 12 个月 0 个）

## 中文简介

用于嵌入数据和分级的可拖放可排序组件

## 安装

```sh
npm install @exytab/react-sortable-tree
```

也可以使用：`pnpm add @exytab/react-sortable-tree`、`yarn add @exytab/react-sortable-tree`、`bun add @exytab/react-sortable-tree`

## README

# 注:支持反应-DND:16,反应:17/18/19

# 注意: 不支持 React 严格模式

![](https://cloud.githubusercontent.com/assets/4413963/18860410/26f64de8-84b8-11e6-9284-350308eed30a.png)

# 反应可排序树

![NPM version](https://img.shields.io/npm/v/@exytab/react-sortable-tree.svg?style=flat) ![NPM license](https://img.shields.io/npm/l/@exytab/react-sortable-tree.svg?style=flat) [![NPM total downloads](https://img.shields.io/npm/dt/@exytab/react-sortable-tree.svg?style=flat)](https://npmcharts.com/compare/@exytab/react-sortable-tree?minimal=true) [![NPM monthly downloads](https://img.shields.io/npm/dm/@exytab/react-sortable-tree.svg?style=flat)](https://npmcharts.com/compare/@exytab/react-sortable-tree?minimal=true) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com/)

> 用于分级数据的可拖放排序的响应组件。 检查 [故事书](https://exytab.github.io/react-sortable-tree/) 展示一些基本和先进的特征.

![](https://cloud.githubusercontent.com/assets/4413963/19334888/2be8261c-913a-11e6-9508-4b347ae114b4.gif)

## 目录

-   [开始](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-getting-started)
-   [使用量](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-usage)
-   [道具](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-props)
-   [数据助手](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-data-helper-functions)
-   [主题](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-themes)
-   [浏览器兼容性](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-browser-compatibility)
-   [解决问题](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-troubleshooting)
-   [捐款](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-contributing)

## 开始

安装 `react-sortable-tree` 使用 npm.

```sh
# NPM
npm install @exytab/react-sortable-tree --save

# YARN
yarn add @exytab/react-sortable-tree
```

ES6和CommonJS的建筑随每次分发而提供. 例如:

```js
// This only needs to be done once; probably during your application's bootstrapping process.
import '@exytab/react-sortable-tree/dist/style.css';

// You can import the default tree with dnd context
import SortableTree from '@exytab/react-sortable-tree';

// Or you can import the tree without the dnd context as a named export. eg
import { SortableTreeWithoutDndContext as SortableTree } from '@exytab/react-sortable-tree';

// Importing from cjs (default)
import SortableTree from '@exytab/react-sortable-tree/dist/index.cjs.js';
import SortableTree from '@exytab/react-sortable-tree';

// Importing from esm
import SortableTree from '@exytab/react-sortable-tree/dist/index.esm.js';
```

## 使用量

```jsx
import React, { Component } from 'react';
import SortableTree from '@exytab/react-sortable-tree';
import '@exytab/react-sortable-tree/dist/style.css'; // This only needs to be imported once in your app

export default class Tree extends Component {
  constructor(props) {
    super(props);

    this.state = {
      treeData: [
        { title: 'Chicken', children: [{ title: 'Egg' }] },
        { title: 'Fish', children: [{ title: 'fingerline' }] },
      ],
    };
  }

  render() {
    return (
      <div style={{ height: 400 }}>
        <SortableTree
          treeData={this.state.treeData}
          onChange={treeData => this.setState({ treeData })}
        />
      </div>
    );
  }
}
```

## 道具

| Prop | 类型 | 
说明

 |
| :-- | :-- | :-: |
| 树数据  
_(必须)_ | 对象\[\] | 带有下列密钥的树数据 :

`title` 是节点的主要标签.

`subtitle` 是节点的二级标签.

`expanded` 若为真,则显示节点的子孙,若为假,则隐藏它们。 默认为假.

`children` 是属于节点的儿童节点数组.

**示例**数字 : `[{title: 'main', subtitle: 'sub'}, { title: 'value2', expanded: true, children: [{ title: 'value3') }] }]`

 |
| 变化  
_(必须)_ | 乐趣c | 当树数据改变时调用 。 与 React 输入元素一样,您必须更新自己组件的数据才能看到变化得到反映.

`( treeData: object[] ): void`

 |
| 获取节点键  
_(建议)_ | 乐趣c | 指定用于识别每个节点并生成该节点的唯一密钥 `path` 数组通过回调。 设定 `getNodeKey={({ node }) => node.id}`例如,在召回中,这会让你很容易地确定带一个 `id` 联 合 国 `35` 是(或刚刚成为)一个节点的孩子 `id` 联 合 国 `12`这是... 的孩子,等等。 用这个 [`defaultGetNodeKey`](https://npmcn.com/package/%40exytab/react-sortable-tree/src/utils/default-handlers.ts) 默认,它返回树上的索引(隐藏节点).

`({ node: object, treeIndex: number }): string or number`

 |
| 生成节点方案 | 乐趣c | 生成一个带有附加道具的物体来传递给节点渲染器. 用于通过 : `buttons` 键,或额外 `style` 编号 : `className` 设置.

`({ node: object, path: number[] or string[], treeIndex: number, lowerSiblingCounts: number[], isSearchMatch: bool, isSearchFocus: bool }): object`

 |
| 移动节点 | 乐趣c | 在节点移动操作后调用 .

`({ treeData: object[], node: object, nextParentNode: object, prevPath: number[] or string[], prevTreeIndex: number, nextPath: number[] or string[], nextTreeIndex: number }): void`

 |
| 关于可视性切换 | 乐趣c | 儿童节点倒塌或扩大后打电话.

`({ treeData: object[], node: object, expanded: bool, path: number[] or string[] }): void`

 |
| 在德拉格州变更 | 乐趣c | 当拖曳启动或结束时调用 .

`({ isDragging: bool, draggedNode: object }): void`

 |
| 最大深度 | 编号 | 可插入最大深度节点 。 默认无限. |
| 行方向 | 字符串 | 如果设置为 `'rtl'` 默认为 `'ltr'`。 。 。 . |
| 罐头 | func 或 bool (英语) | 通过隐藏拖动柄,从回调返回假来防止节点被拖动. 设置道具为 `false` 以禁用在所有节点上拖曳。 默认为 `true`。 。 。 .

`({ node: object, path: number[] or string[], treeIndex: number, lowerSiblingCounts: number[], isSearchMatch: bool, isSearchFocus: bool }): bool`

 |
| 扫描 | 乐趣c | 返回假以阻止节点在指定位置下降.

`({ node: object, prevPath: number[] or string[], prevParent: object, prevTreeIndex: number, nextPath: number[] or string[], nextParent: object, nextTreeIndex: number }): bool`

 |
| 可选择有孩子 | 乐趣c | 用于确定一个节点是否可以有子的函数, 用于防止在您有时的悬浮预览 `canDrop` 条件。 默认设置为返回函数 `true`函数应属于类型 `(node): bool`。 。 。 . |
| 主题 | 对象 | 为树设置一一包外观. 见 [主题](https://npmcn.com/package/%40exytab/react-sortable-tree/#readme-themes) 用于提供更多信息. |
| 搜索方法 | 乐趣c | 用于搜索节点的方法. 默认为 [`defaultSearchMethod`](https://npmcn.com/package/%40exytab/react-sortable-tree/src/utils/default-handlers.ts),使用 `searchQuery` 搜索匹配节点的字符串 `title` 或者说 `subtitle` 数值。 注:变化 `searchMethod` 将不更新搜索,而是更改 `searchQuery` 会的.

`({ node: object, path: number[] or string[], treeIndex: number, searchQuery: any }): bool`

 |
| 搜索查询 | 字符串或任意 | 用于 `searchMethod` 以突出显示并滚动以匹配节点。 默认应为字符串 `searchMethod`,但使用自定义搜索时可以做任何事情。 默认为 `null`。 。 。 . |
| 搜索焦点 | 编号 | 大纲 <`searchFocusOffset`\>th节点并滚动到它. |
| 只扩展已删除的节点 | 布尔 | 只扩展匹配搜索的节点 。 折叠所有其他节点。 默认为 `false`。 。 。 . |
| 搜索 Finish 回击 | 乐趣c | 获取匹配搜索标准的节点 。 用于计算总匹配等.

`(matches: { node: object, path: number[] or string[], treeIndex: number }[]): void`

 |
| 代码 | 字符串 | 使用的字符串值 [反应-dnd](https://react-dnd.github.io/react-dnd/about) (请参见链接中的概览)用于滴入目标与拖曳源类型. 如果未明确设定, 默认值会通过反应- 类型- 树来应用, 供您内部使用 . **注:** 要正确运行外部节点,必须明确设置并使用相同的值 |
| 应在外部复制 | func 或 bool (英语) | 返回真,或调回真,并放出节点来进行树外的反应-dnd投放目标不会将其从树上取出. 默认为 `false`。 。 。 .

`({ node: object, prevPath: number[] or string[], prevTreeIndex: number, }): bool`

 |
| 样式 | 对象 | 用于包装树的容器的样式(样式默认为 `{height: '100%'}`(中文(简体) ) |
| 内层 | 对象 | 适用于内部可滚动容器的样式(用于铺垫等) |
| 类Name | 字符串 | 包装树的容器的类名 |
| 幻灯片 | 编号 | 边缘附近区域 px 的大小, 以拖放方式启动滚动 。 默认为 `100`。 。 。 . |
| 脚手架BlockPxWidth | 编号 | 包含代表树的结构的线条的区块的宽度. 默认为 `44`。 。 。 . |
| 节点连接器 | 任意 | 覆盖默认组件( N)[`NodeRendererDefault`](https://npmcn.com/package/%40exytab/react-sortable-tree/src/node-renderer-default.tsx)用于渲染节点(但保留脚手架生成器). 这是定制的最后手段 - 大多数定制样式应该能够用 `generateNodeProps`页:1 `theme` 或CSS规则。 如果您必须使用, 最好将组件复制到 `node-renderer-default.tsx` 并按需要定制. |
| 占位符渲染器 | 任意 | 覆盖默认占位符组件( E)[`PlaceholderRendererDefault`](https://npmcn.com/package/%40exytab/react-sortable-tree/src/placeholder-renderer-default.tsx)当树为空时显示。 这是一个先进的选择,在多数情况下,也许应该用 `theme` 或自定义 CSS 代替. |
| 虚拟技术 | 对象 | 直接设置于底部的属性 [维图索语Name](https://virtuoso.dev/virtuoso-api-reference/) 组件. |
| 参考文献 | 参考 | A 类 [参考文献](https://react.dev/learn/manipulating-the-dom-with-refs) 如何利用基础 [维图索语Name](https://virtuoso.dev/virtuoso-api-reference/) 组件的方法. |

## 数据辅助函数

需要手把你的平面数据变成嵌入的树数据吗? 想要在树数据上执行添加/移动操作而不创建自己的递归函数吗 ? 检查导出到的助手函数 [`tree-data-utils.ts`](https://npmcn.com/package/%40exytab/react-sortable-tree/src/utils/tree-data-utils.ts)。 。 。 .

-   **`getTreeFromFlatData`**: 将平面数据(如数据库中的数据)转换为嵌入树数据.
-   **`getFlatDataFromTree`**: 将树数据转换回平面数据.
-   **`addNodeUnderParent`**:在给定路径的父节点下添加一个节点.
-   **`removeNode`**: 对于给定的路径, 获取该路径的节点, treeIndex, 以及带有该节点的树数据 .
-   **`removeNodeAtPath`**:对于给定的路径,去掉节点并返回树数据.
-   **`changeNodeAtPath`**: 修改给定路径上的节点对象.
-   **`map`**:在树上的每一个节点上执行一个变化.
-   **`walk`**:按顺序访问树上每个节点.
-   **`getDescendantCount`**:计算这个节点有多少后代.
-   **`getVisibleNodeCount`**:计算这个节点有多少能见度的后人.
-   **`getVisibleNodeInfoAtIndex`**:在树上数据中获取可见节点.
-   **`toggleExpandedForAll`**: 扩展或关闭树上每个节点.
-   **`getNodeAtPath`**:在输入路径取出节点.
-   **`insertNode`**: 在指定的深度和最小TreeIndex上插入输入节点.
-   **`find`**: 在树上查找匹配搜索查询的节点.
-   **`isDescendant`**:检查一个节点是否是另一个节点的后人.
-   **`getDepth`**:得到树上最长的路径.

## 主题

使用 `theme` prop与导入的主题模块一起,您可以轻松地将默认外观与另一个标准外观相覆盖.

### 专题

| ![File Explorer Theme](https://user-images.githubusercontent.com/4413963/32144502-1df1ae08-bcfd-11e7-8f63-8b836dace1a4.png) | ![Full Node Drag Theme](https://user-images.githubusercontent.com/4413963/33521792-61dc2c50-d81f-11e7-8ab1-359661a11ca4.png) | ![MINIMAL THEME](https://github.com/lifejuggler/react-sortable-tree-theme-minimal/blob/master/example-resource/main.png) |
| :-- | :-- | :-: |
| **文件浏览器** | **全节点拖曳** | **受物质UI启发的最小化主题** |
| @nosferatu500/主题文件-探索者 | 反应 - 调味树 - 主题 - 完全节点 - 道格 | 反应 - 各类树木 - 主题 - 最小 |
| [吉图布](https://github.com/nosferatu500/theme-file-explorer) | [国家预防机制](https://www.npmjs.com/package/@nosferatu500/theme-file-explorer) | [吉图布](https://exytab.github.io/react-sortable-tree/react-sortable-tree-theme-full-node-drag) | [国家预防机制](https://www.npmjs.com/package/react-sortable-tree-theme-full-node-drag) | [吉图布](https://github.com/lifejuggler/react-sortable-tree-theme-minimal) | [国家预防机制](https://www.npmjs.com/package/react-sortable-tree-theme-minimal) |

**需要帮助** - 由于主题功能刚刚启用,因此很少(只有 _两个_ )主题模块。 如果你已经定制了你的树的外观 以特别酷或容易使用, 我很乐意在读本中显示它 与Github repo和国家预防机制的页面链接 如果你把它转换成一个主题。 你可以用我的车 [文件探索器主题repo](https://github.com/nosferatu500/theme-file-explorer) 作为插入自己东西的模板.

## 浏览器兼容性

| 浏览器 | 工作吗? |
| :-- | :-- |
| 颜色 | 对 |
| 火花 | 对 |
| 萨法里 | 对 |
| IE 11 请检查URL=值 (帮助) | 对 |

## 解决问题

### 如果在生产中抛出“ TypeError: fn 不是函数” 错误

这个问题可能与UglifyJS和Webpack行为的持续不相容有关. 参见 [创建- react-app # 2376](https://github.com/facebookincubator/create-react-app/issues/2376)。 。 。 .

减轻这一问题的最简单方法是增加: `comparisons: false` 到您在此看到的丑化配置 : [https://github.com/facebookincubator/create-react-app/pull/2379/files 互联网档案馆的存檔,存档日期2013-12-29](https://github.com/facebookincubator/create-react-app/pull/2379/files)

### 如果与其他使用反应-dnd的组件不起作用

反应-dnd只允许一次一个 DragDropContext(见: [https://github.com/gaearon/react-dnd/issues/186 (中文(简体) )](https://github.com/gaearon/react-dnd/issues/186)) (中文(简体) ). 要绕过这里, 您可以通过 `SortableTreeWithoutDndContext`。 。 。 .

```js
// before
import SortableTree from '@exytab/react-sortable-tree';

// after
import { SortableTreeWithoutDndContext as SortableTree } from '@exytab/react-sortable-tree';
```

## 捐款

请读一下 [行为守则](https://npmcn.com/package/%40exytab/react-sortable-tree/CODE_OF_CONDUCT.md)我积极欢迎拉动请求:)

复制寄存器并运行后 `yarn install` 在内部,可以使用以下命令来开发和构建工程.

```sh
# Starts a webpack dev server that hosts a demo page with the component.
# It uses react-hot-loader so changes are reflected on save.
yarn start

# Start the storybook, which has several different examples to play with.
# Also hot-reloaded.
yarn run storybook

# Runs the library tests
yarn test

# Lints the code with eslint
yarn run lint

# Lints and builds the code, placing the result in the dist directory.
# This build is necessary to reflect changes if you're
#  `npm link`-ed to this repository from another local project.
yarn run build
```

拉请求是欢迎的!

## 许可证

麻省理工学院

## 常见问题

### @exytab/react-sortable-tree 是什么？

用于嵌入数据和分级的可拖放可排序组件

### 如何安装 @exytab/react-sortable-tree？

在项目目录运行 npm install @exytab/react-sortable-tree，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^17\.0\.0 \|\| ^18\.0\.0 \|\| ^19\.0\.0）、react-dnd（16\.0\.1）、react-dom（^17\.0\.0 \|\| ^18\.0\.0 \|\| ^19\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @exytab/react-sortable-tree 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @exytab/react-sortable-tree 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @exytab/react-sortable-tree 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @exytab/react-sortable-tree 可以商用吗？

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

### @exytab/react-sortable-tree 的下载量有多少？

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

### @exytab/react-sortable-tree 还在维护吗？

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

