TypeError: 提交表单时,.map 不是一个函数

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

TypeError: .map is not a function when submit a form

问题

我有一个问题,我正在尝试创建一个选择表单,在这个表单中,选择一个选项应该将对象中的布尔值从available: true切换为false。我认为我的解决方案很有前途,但我收到了错误消息。

import { useState } from 'react';

function App() {
  const [time, setTime] = useState("");
  const [availableSlots, setAvailableSlots] = useState([
    { value: '17:00', available: true },
    { value: '18:00', available: true },
    { value: '19:00', available: true },
    { value: '20:00', available: true },
    { value: '21:00', available: true },
    { value: '22:00', available: true }
  ]);

  const toggleAv = () => {
    var selectedSlot = availableSlots.find((item) => {
      return item.value === time;
    });
    setAvailableSlots(
      ...availableSlots,
      selectedSlot.available = false
    );
    console.log(availableSlots);
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    toggleAv();
  }

  return (
    <>
      <form onSubmit={handleSubmit}>
        <select
          name="time"
          id="time"
          value={time}
          onChange={(e) => setTime(e.target.value)}
        >
          {availableSlots.map((item, key) => {
            return <option key={key} value={item.value}>{item.value}</option>;
          })}
        </select>
        <input type="submit" value="Submit" />
      </form>
    </>
  );
}

export default App;

代码在应该的情况下运行正常,只是在提交时出现错误。我应该使用其他方法替代find吗?我不明白为什么不能像这样使用.filter方法...

英文:

I have a problem I am trying to make a select form where the selection of an option suppose to toggle boolean value in an object from available: true to false. I think my solution is quite promising but I am getting error

import { useState } from &#39;react&#39;
function App() {
const [time, setTime] = useState(&quot;&quot;)
const [availableSlots, setAvailableSlots] = useState([
{value: &#39;17:00&#39;, available: true},
{value: &#39;18:00&#39;, available: true},
{value: &#39;19:00&#39;, available: true},
{value: &#39;20:00&#39;, available: true},
{value: &#39;21:00&#39;, available: true},
{value: &#39;22:00&#39;, available: true}
])
const toggleAv = () =&gt; {
var selectedSlot = availableSlots.find((item) =&gt; {
return item.value === time
})
setAvailableSlots(
...availableSlots,
selectedSlot.available = false
)
console.log(availableSlots)
}
const handleSubmit = (e) =&gt; {
e.preventDefault();
toggleAv()
}
return (
&lt;&gt;
&lt;form onSubmit={handleSubmit}&gt;
&lt;select 
name=&quot;time&quot; 
id=&quot;time&quot; 
value={time} 
onChange={(e) =&gt; setTime(e.target.value)}
&gt;
{availableSlots.map((item, key) =&gt; {
return &lt;option key={key} value={item.value}&gt;{item.value}&lt;/option&gt;
})}
&lt;/select&gt;
&lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
&lt;/form&gt;
&lt;/&gt;
)
}
export default App

Code works how it should, it just gives error when submitted. Should I use something else instead of find then? I don't see any reason why I couldn't use the .filter method like that...

答案1

得分: 2

这是包含解决方案的 codesandbox 存储库。我只是创建了一个具有更新的“available”属性的新插槽数组,然后将该新数组传递给了setAvailableSlots(),而不是展开现有的availableSlots数组。

这是更新后的函数:

const toggleAv = () => {
  const updatedSlots = availableSlots.map((slot) =>
    slot.value === time ? { ...slot, available: false } : slot
  );
  setAvailableSlots(updatedSlots);
  console.log(updatedSlots);
};
英文:

here is codesandbox repo with the solution. I just created a new array of slots with the updated "available" properties and then passed that new array to the setAvailableSlots() instead of spreading the existing availableSlots array.

here is updated function

  const toggleAv = () =&gt; {
const updatedSlots = availableSlots.map((slot) =&gt;
slot.value === time ? { ...slot, available: false } : slot
);
setAvailableSlots(updatedSlots);
console.log(updatedSlots);
};

答案2

得分: 0

使用一个for循环,在匹配到索引的时间时更新数值。你正在尝试使用的是扩展运算符。它会保留先前的值并添加一个不是对象类型的额外项。因此,它不会使用.map()函数。

  const toggleAv = () => {

    for (var i = 0; i < availableSlots.length; i++) {
      if (availableSlots[i].value === time) {
        availableSlots[i].available = false;
      }
    }
  };
英文:

Use a for loop where it matches the time at index it will update the value. The code you are trying it is a spread operator. It will keep previous values and add one more item which is not a object kind. So it is not taking the .map() function.

const toggleAv = () => {

for (var i = 0; i &lt; availableSlots.length; i++) {
if (availableSlots[i].value === time) {
availableSlots[i].available = false;
}
}

};

huangapple
  • 本文由 发表于 2023年7月20日 10:45:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76726363.html
匿名

发表评论

匿名网友

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

确定