You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Typeahead多选组件移除项问题:自定义Token无删除按钮

解决React-Bootstrap-Typeahead多选组件自定义Token无删除叉号及移除项问题

我看了你的代码,问题主要出在两个地方:自定义Token没有正确传递删除逻辑,以及缺少删除按钮的渲染。下面一步步帮你解决:

问题分析

  1. onRemove函数传递错误:你在getSkillEffectToken里写的onRemove只是传递了一个布尔值(未赋值),并没有把实际的删除函数传给TokenSkill组件,导致点击删除时没有触发逻辑。
  2. 自定义Token未包含删除按钮:原Token组件自带删除叉号和对应的触发逻辑,但你用自定义div完全替代了原组件的结构,所以看不到删除按钮,自然无法移除选项。

解决方案

我们分两种情况处理,你可以根据需求选择:

方案1:保留原Token的删除按钮,同时自定义交互

这种方式会复用原Token组件的删除样式和逻辑,只添加你需要的自定义点击事件:

import React from "react";
import { render } from "react-dom";
import { Token, tokenContainer, Typeahead } from "react-bootstrap-typeahead";

const styles = { fontFamily: "sans-serif", textAlign: "center" };

// 用tokenContainer包装原Token组件,添加自定义点击逻辑
const TokenSkill = tokenContainer((props) => {
  const { onRemove, onClickCustom, ...restProps } = props;
  
  return (
    <Token
      {...restProps}
      onClick={(event) => {
        event.stopPropagation();
        onClickCustom(event);
      }}
      onRemove={onRemove}
    >
      {props.children}
    </Token>
  );
});

class App extends React.Component {
  render = () => {
    const options = [
      { id: "house", name: "House" },
      { id: "house2", name: "House2" },
      { id: "house3", name: "House3" }
    ];
    return (
      <Typeahead
        clearButton
        labelKey="name"
        multiple
        allowNew
        onChange={(selectedItems) => console.log("选中项变化:", selectedItems)} // 修正onChange写法
        options={options}
        placeholder="Choose a state..."
        renderToken={(option, onRemove, index) => this.getSkillEffectToken(option, onRemove, index)}
      />
    );
  };

  getSkillEffectToken = (option, onRemove, index) => {
    return (
      <TokenSkill
        onRemove={onRemove} // 正确传递删除函数
        key={index}
        onClickCustom={(event) => {
          alert("自定义点击事件触发!");
        }}
      >
        {`${option.name}`}
      </TokenSkill>
    );
  };
}

render(<App />, document.getElementById("root"));

方案2:完全自定义Token外观,手动添加删除按钮

如果你想完全控制Token的样式,可以自己添加删除按钮并绑定删除逻辑:

import React from "react";
import { render } from "react-dom";
import { tokenContainer, Typeahead } from "react-bootstrap-typeahead";

const styles = { fontFamily: "sans-serif", textAlign: "center" };

// 完全自定义Token结构,手动添加删除按钮
const TokenSkill = tokenContainer((props) => {
  const { onRemove, onClickCustom, children, ...restProps } = props;
  
  return (
    <div 
      {...restProps} 
      className="tokenSkill" 
      tabIndex={0}
      style={{ 
        display: "inline-flex", 
        alignItems: "center", 
        margin: "0 4px 4px 0",
        padding: "4px 8px",
        border: "1px solid #ccc",
        borderRadius: "4px",
        backgroundColor: "#f8f9fa"
      }}
    >
      <span 
        onClick={(event) => {
          event.stopPropagation();
          onClickCustom(event);
        }}
        style={{ cursor: "pointer" }}
      >
        {children}
      </span>
      <button
        onClick={(event) => {
          event.stopPropagation();
          onRemove(); // 触发删除逻辑
        }}
        style={{
          marginLeft: "8px",
          border: "none",
          backgroundColor: "transparent",
          cursor: "pointer",
          fontSize: "16px",
          padding: "0",
          width: "16px",
          height: "16px",
          display: "flex",
          alignItems: "center",
          justifyContent: "center"
        }}
      >
        ×
      </button>
    </div>
  );
});

class App extends React.Component {
  render = () => {
    const options = [
      { id: "house", name: "House" },
      { id: "house2", name: "House2" },
      { id: "house3", name: "House3" }
    ];
    return (
      <Typeahead
        clearButton
        labelKey="name"
        multiple
        allowNew
        onChange={(selectedItems) => console.log("选中项变化:", selectedItems)}
        options={options}
        placeholder="Choose a state..."
        renderToken={(option, onRemove, index) => this.getSkillEffectToken(option, onRemove, index)}
      />
    );
  };

  getSkillEffectToken = (option, onRemove, index) => {
    return (
      <TokenSkill
        onRemove={onRemove}
        key={index}
        onClickCustom={(event) => {
          alert("自定义点击事件触发!");
        }}
      >
        {`${option.name}`}
      </TokenSkill>
    );
  };
}

render(<App />, document.getElementById("root"));

额外注意点

  • 修正了Typeahead的onChange写法:原来的onChange={console.log("toot!")}会在组件渲染时立即执行,改为箭头函数后才会在选中项变化时触发。
  • 用event.stopPropagation()防止点击自定义内容时误触发Token的默认删除逻辑。

内容的提问来源于stack exchange,提问作者Umbro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:19:10