React Typeahead多选组件移除项问题:自定义Token无删除按钮
解决React-Bootstrap-Typeahead多选组件自定义Token无删除叉号及移除项问题
我看了你的代码,问题主要出在两个地方:自定义Token没有正确传递删除逻辑,以及缺少删除按钮的渲染。下面一步步帮你解决:
问题分析
onRemove函数传递错误:你在getSkillEffectToken里写的onRemove只是传递了一个布尔值(未赋值),并没有把实际的删除函数传给TokenSkill组件,导致点击删除时没有触发逻辑。- 自定义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
相关产品推荐
相关产品推荐

