【问题标题】:how to match an inputs value to a .map function pulling data from an api如何将输入值与从 api 提取数据的 .map 函数匹配
【发布时间】:2021-12-30 10:29:58
【问题描述】:

我有一个 .map 函数显示从 api 中提取的数据,我想在数据中添加一个字段并使其与相关数据相匹配。

例如,我从一个包含数量的 api 中提取成分,我想添加一个输入字段,允许我添加一个乘数,以后可以用来乘以成分。

这里是 .map 函数:

 <div className="mt-4 border-t border-b border-gray-200 divide-y divide-gray-200">
              {data.ingredients.map((ingredient) => (
                <div
                  key={ingredient.id}
                  className="relative flex items-start py-4"
                >
                  <div className="ml-4 flex items-center h-5">
                    <input
                      onChange={selectIngredient(ingredient.id)}
                      value={selectedIngredients.indexOf(ingredient.id === -1)}
                      type="checkbox"
                      className="focus:ring-purple-500 h-4 w-4 text-purple-600 border-gray-300 rounded"
                    />
                  </div>

                  <div className="ml-3 text-sm">
                    <label
                      className="font-medium text-gray-700 select-none"
                    >
                      {ingredient.name}
                    </label>
                  </div>
                  <div className="ml-3 text-sm">
                  // Here I am using useState to set a multiplier, but it sets the same vale for all data in the .map list.
                    <input
                      value={multiplier}
                      onChange={(e) => setMultiplier(e.target.value)}
                      type="number"
                      className="flex-1 focus:ring-purple-500 focus:border-purple-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300"
                    />
                  </div>
                </div>
              ))}
            </div>

成分对象如下所示:

ingredient: {
id: 1,
name: sugar,
quantity: 100,
quantityUnit: grams,
}

有没有办法设置与相关映射数据相关联的状态?

【问题讨论】:

  • 我建议您将 API 中的所有数据存储到一个状态中,并为您获得的每个 ingredient 添加一个 multiplier 属性。然后使用该数据集来呈现您的字段。
  • 谢谢@EmielZuurbier,我如何将单个的乘数添加到状态?

标签: javascript arrays reactjs


【解决方案1】:

在您的组件中,创建一个新状态。我们称其为具有setIngredients 调度程序的ingredients 状态。默认设置为空数组。

const [ingredients, setIngredients] = useState([]);

使用useEffect 钩子,使用.map() 方法循环接收到的数据,并从添加了multiply 属性的每个成分返回一个新对象。使用这个新的对象数组更新 ingredients 状态。

useEffect(() => {
  if (data.length) {
    setIngredients(
      data.map(ingredient => ({
        ...ingredient,
        multiply: 1
      })
    );
  }
}, [data]);

现在您的ingredients 状态包含所有成分以及每种成分的multiply 属性。

为了确定,我添加了这段(伪)代码来演示解决方案应该如何工作。

现在每种成分都有一个multiply 属性,默认设置为1。在您的表单中添加一个处理乘法值的新输入。用户可以使用输入来改变乘法。

如果需要,您还可以添加隐藏输入来跟踪成分的总数量(数量 * 相乘)。这在您提交表单时可能会派上用场。

const handleMultiplyChange = (event, id) => {
  const value = Number(event.value)
  const updatedIngredients = ingredients.map(ingredient => ({
    ...ingredient,
    multiply: ingredient.id === id ? value : ingredient.multiply
  }));

  setIngredients(updatedIngredients);
};

return (ingredients.map(ingredient => (
  <>
    <input 
      type="checkbox"
      name="ingredient"
      value={ingredient.id}
    />
    <input 
      type="number" 
      name="multiply"
      min="1"
      value={ingredient.multiply}
      onChange={(event) => handleMultiplyChange(event, ingredient.id)}
    />
    <input 
      type="hidden"
      name="totalQuantity"
      value={(ingredient.multiply * ingredient.quantity)}
    />
  </>
));

【讨论】:

  • 非常感谢您的回答。我唯一的是不同成分的乘数会有所不同。例如,一种成分可能是 100 克糖,而配方可能需要 500 克糖,对于不同的成分,糖的乘数将是 5,依此类推。我怎样才能做到这一点?
  • 乘数基于什么?您的数据是否包含有关它的任何信息,或者您是否包含?您能否通过将其编辑到您的问题中来分享单个成分对象的外观?
  • 基本上,我想在将要提交以创建食谱的表单上列出所有成分。因此,为此将创建配方的用户将选择适当的成分。成分以默认数量(例如 100 克糖)存储在数据库中,用户将选择配方的相关成分复选框,然后添加一个乘数,将默认成分数量乘以配方的所需数量.我希望这对乘数的作用有意义。当然,我可以更新它。
  • 我明白你的意思。这意味着该解决方案仍然有效,因为每种成分都有自己的乘数。您甚至可以将每种成分的乘法结果存储在隐藏的输入中,以便在提交时与表单一起发送。
  • 太棒了,非常感谢。今天会试试这个,让你知道我的进展!
猜你喜欢
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多