【问题标题】:Rendering a label for multiple dropdown selection为多个下拉选择呈现标签
【发布时间】:2021-03-19 12:31:56
【问题描述】:

我有一个多重下拉选择,可让您选择食物项目,然后单击时可以在末尾添加文本值。我正在为 Dropdown 组件使用“semantic-UI-react”。我的问题是,当我将新值添加到嵌套对象时,标签会消失。我可以使用所需的值设置标签或嵌套对象,但是当我尝试一起做时,标签总是消失。图片供参考

这是我以这种方式工作的代码:

const renderLabel = (item, i, { value }) => ({
    content: value,
    onClick: (e) => {
      const servingSize = prompt(value + ' serving size:');
      if (servingSize !== null) {
        value = item.text + ' ' + servingSize;
        e.target.firstChild.textContent = value;
      };
    }
  });

<Dropdown clearable id="breakfast-fruits1" renderLabel={renderLabel} search allowAdditions onAddItem={handleAddition} className="dropdown" placeholder="Fruits" fluid multiple selection options={fruits} onChange={handleChange} />

当我尝试设置状态时,最后一个标签消失了。

const renderLabel = (item, i, { value }) => ({
    content: value,
    onClick: (e) => {
      const servingSize = prompt(value + ' serving size:');
      if (servingSize !== null) {
        value = item.text + ' ' + servingSize;
        e.target.firstChild.textContent = value;
        setResult((prevResult) => {
          prevResult.monday.breakfast.fruits[i] = value;
          return prevResult;
        })
      };
    }
  });

关于如何使其工作或设置更好的任何想法?我尝试了许多不同的方法来呈现标签并更改状态/结果。让我知道我是否可以在问题中包含其他任何内容以使其更易于解决。

这是我的水果状态:

const [ fruits, setFruits ] = useState([
    { key: 'Apple', text: 'Apple', value: 'Apple' },
    { key: 'Apricot', text: 'Apricot', value: 'Apricot' },
    { key: 'Banana', text: 'Banana', value: 'Banana' },
    { key: 'Berries', text: 'Berries', value: 'Berries' },
    { key: 'Blackberries', text: 'Blackberries', value: 'Blackberries' },
    { key: 'Blueberries', text: 'Blueberries', value: 'Blueberries' },
    { key: 'Cantaloupe', text: 'Cantaloupe', value: 'Cantaloupe' },
    { key: 'Cherries', text: 'Cherries', value: 'Cherries' },
    { key: 'Grapefruit', text: 'Grapefruit', value: 'Grapefruit' },
    { key: 'Honeydew', text: 'Honeydew', value: 'Honeydew' },
    { key: 'Kiwi', text: 'Kiwi', value: 'Kiwi' },
    { key: 'Melon', text: 'Melon', value: 'Melon' },
    { key: 'Nectarine', text: 'Nectarine', value: 'Nectarine' },
    { key: 'Orange', text: 'Orange', value: 'Orange' },
    { key: 'Papaya', text: 'Papaya', value: 'Papaya' },
    { key: 'Peach', text: 'Peach', value: 'Peach' },
    { key: 'Pear', text: 'Pear', value: 'Pear' },
    { key: 'Pineapple', text: 'Pineapple', value: 'Pineapple' },
    { key: 'Plum', text: 'Plum', value: 'Plum' },
    { key: 'Raspberries', text: 'Raspberries', value: 'Raspberries' },
    { key: 'Strawberries', text: 'Strawberries', value: 'Strawberries' },
    { key: 'Tangerine', text: 'Tangerine', value: 'Tangerine' },
    { key: 'Watermelon', text: 'Watermelon', value: 'Watermelon' }
  ]);

这是我的 onChange 函数:

const handleChange = (e, { value }) => {
    const newData = update(result, {
      monday: {breakfast: {fruits: {$set: value}}}
    });
    setResult(newData);
  };

这是我的 handleAddition 函数:

const handleAddition = (e, data) => {
    console.log(data.value);
    setFruits((prevFruits) => {
      return [
        ...prevFruits,
        { text: data.value, key: data.value, value: data.value }
      ];
    });
  };

【问题讨论】:

    标签: javascript reactjs react-native react-hooks semantic-ui-react


    【解决方案1】:

    我建议将问题分解为 2 个单独的部分:renderLabel 应该只渲染标签并返回 JSX 以显示在屏幕上,让我们定义一个处理状态更新的新函数。如果我们可以使状态更新正常运行,则渲染标签可以处理更新新的视觉效果。

    让我们开始吧。

    这里的renderLabel函数应该只有一个目的,就是在React组件渲染和重新渲染时显示标签。

    在您的代码 sn-p 编号 2 中,您似乎正在尝试使用 React Hook setResult 来更改应用程序的状态。建议定义一个单独的函数,例如onLabelClick,然后负责更新状态。

    更新

    我为此问题编写了 CodePen 并测试了您的代码的功能。 您可以查看My CodePen Dropdown Test似乎选择选项值更改文本时更改。这些更改不会保存在选项对象中。

    我没有解决问题,让我们看看CodePen是否有帮助。

    关于状态管理

    最后,代码 sn-p 2 改变了 prevState 的状态,这是状态更新系统中的一种反模式。始终复制先前的状态并与新的子状态合并,例如使用

    const newState = {...prevState, nameOfTheProperyToOverrideInPrevState: newValue};
    

    这可以防止应用程序中的错误。一些流行的状态管理系统例如

    • Redux
    • 使用 Hooks 状态的功能组件
    • 不可变的.js

    了解它们的工作原理有助于更深入地了解状态更新为何会失败。

    【讨论】:

    • 是的,我绝对相信它尝试更新状态失败。我试图按照您上面显示的方式制作副本。我也尝试过使用“immutability-helper”进行更新,但标签仍然消失了。它确实会正确更新状态,但只要状态更新,渲染标签就会消失。您提供的 renderLabel 函数可以正确渲染标签。你对我应该如何解决这个问题有任何其他建议吗?只是让你知道是的,有一个 setResult 钩子。
    • 感谢您试用!我需要查看更多代码才能查明问题,尤其是您如何定义 options={fruits}。您似乎正在尝试编辑标签 option 的值,并通过覆盖现有值来保存该信息。我们能否以不覆盖 prevState 而是复制并设置新状态,然后将其删除/传递给 options 属性的方式使 options={fruits} 动态且不可变?
    • Fruits 是一个状态,它是一个对象数组,例如:[{ key: 'apple', text: 'apple', value: 'apple' }, { key: 'banana', text :'香蕉',价值:'香蕉'}]。我使用 onChange 将其值转换为结果状态,并使用它添加当前不在下拉选项中的其他食品。分享更多代码的最佳方式是什么?一般来说,我是堆栈、反应和编码的新手。
    • 我已经添加了上面的附加代码。需要帮助请叫我。感谢您的帮助!
    • 从图片中可以看出,我对所有水果下拉菜单都使用了水果选项。
    猜你喜欢
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2011-11-02
    • 1970-01-01
    相关资源
    最近更新 更多