React-Bootstrap-Typeahead: 使用自定义输入隐藏已选择的标记

huangapple go评论66阅读模式
英文:

React-Bootstrap-Typeahead: Using custom input hides selected tokens

问题

我试图使用自定义输入,并且我已经从RBT Rendering example中复制了示例。我的主要目标是为输入添加一个测试标识(test-id),移除提示,以及为输入使用自定义组件。但出现了一个问题,当我从菜单中选择一个选项时,它不会像示例中那样出现在我的自定义输入中。显然,它被设置到状态中,因为它从可用选项中消失了。我是否需要在我的Form.Control输入周围包装其他内容?

这是一个可工作的沙盒,但为了避免链接失效,我也会粘贴组件代码如下:

<Typeahead
  id={`${testIdPrefix}-medal`}
  labelKey="medal"
  multiple
  placeholder="Choose up to 2"
  options={[
    { medal: "Gold" },
    { medal: "Silver" },
    { medal: "Bronze" },
    { medal: "Tin" }
  ]}
  selected={multiSelections}
  onChange={(selections) => setMultiSelections(selections.slice(-2))}
  renderInput={({ inputRef, referenceElementRef, ...inputProps }) => (
    <Form.Control
      test-id={`${testIdPrefix}-medal`}
      {...inputProps}
      ref={(node) => {
        inputRef(node);
        referenceElementRef(node);
      }}
    />
  )}
  renderToken={(option, { onRemove }, index) => (
    <Token
      key={index}
      onRemove={onRemove}
      option={option}
      className="medal-token"
    >
      {`${option.medal}`}
    </Token>
  )}
/>

复现步骤:

  • 加载沙盒
  • 从菜单中选择一个选项
  • 不会出现令牌(但我期望会出现一个)

注意:即使没有自定义的Token也会出现这个问题,但我包含它以防它与解决方案相关。(我需要解决方案与自定义令牌一起使用。)

英文:

I'm trying to use a custom input and I've copied the example from the RBT Rendering example. My main goals are to add a test-id to the input, to remove the hint, and to use a custom component for the input. For some reason, when I select an option from the menu, it does not appear in my custom input like in the example. It's clearly set into state as it disappears from the available options. Do I need to wrap something else around my Form.Control input?

Here's a working sandbox, but to avoid link-rot, I'll paste the component code below as well.

&lt;Typeahead
  id={`${testIdPrefix}-medal`}
  labelKey=&quot;medal&quot;
  multiple
  placeholder=&quot;Choose up to 2&quot;
  options={[
    { medal: &quot;Gold&quot; },
    { medal: &quot;Silver&quot; },
    { medal: &quot;Bronze&quot; },
    { medal: &quot;Tin&quot; }
  ]}
  selected={multiSelections}
  onChange={(selections) =&gt; setMultiSelections(selections.slice(-2))}
  renderInput={({ inputRef, referenceElementRef, ...inputProps }) =&gt; (
    &lt;Form.Control
      test-id={`${testIdPrefix}-medal`}
      {...inputProps}
      ref={(node) =&gt; {
        inputRef(node);
        referenceElementRef(node);
      }}
    /&gt;
  )}
  renderToken={(option, { onRemove }, index) =&gt; (
    &lt;Token
      key={index}
      onRemove={onRemove}
      option={option}
      className=&quot;medal-token&quot;
    &gt;
      {`${option.medal}`}
    &lt;/Token&gt;
  )}
/&gt;

To reproduce:

  • Load the sandbox
  • Select an option from the menu
  • No token will appear (but I expect one to)

Note: this also happens without the custom Token but I included it in case that's relevant to the solution. (I need the solution to work with a custom token.)

答案1

得分: 1

Yes, multiple={true} 是问题所在。 renderToken 是一个用于自定义令牌渲染的钩子,但如果使用 renderInput,它将不会被调用。在这种情况下,您需要自己处理将选择项渲染为令牌的工作。

作为一个快速示例/测试,您应该能够在 renderInput 中简单地在输入框下方渲染选择项:

renderInput={({ inputRef, referenceElementRef, onRemove, selected ...inputProps }) => (
  <>
    <Form.Control
      test-id={`${testIdPrefix}-medal`}
      {...inputProps}
      ref={(node) => {
        inputRef(node);
        referenceElementRef(node);
      }}
    />
    {selected.map((option, idx) => (
      <Token
        key={idx}
        onRemove={onRemove}
        option={option}
        className="medal-token"
      >
        {option.medal}
      </Token>
    ))}
  </>
)}
英文:

Yes, multiple={true} is the issue. renderToken is a hook into the built-in multi-selection component to customize token rendering, but won't be called if you use renderInput. In that case, you need to handle rendering the selections as tokens yourself.

As a quick example/test, you should be able to simply render the selections below your input in renderInput:

renderInput={({ inputRef, referenceElementRef, onRemove, selected ...inputProps }) =&gt; (
  &lt;&gt;
    &lt;Form.Control
      test-id={`${testIdPrefix}-medal`}
      {...inputProps}
      ref={(node) =&gt; {
        inputRef(node);
        referenceElementRef(node);
      }}
    /&gt;
    {selected.map((option, idx) =&gt; (
      &lt;Token
        key={idx}
        onRemove={onRemove}
        option={option}
        className=&quot;medal-token&quot;
      &gt;
        {option.medal}
      &lt;/Token&gt;
    ))}
  &lt;/&gt;
)}

huangapple
  • 本文由 发表于 2023年5月14日 07:41:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76245281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定