javascript - 应用程序中断,警告 Uncaught TypeError: Cannot read property 'some' of undefined in React
问题描述
我有 3 个部分的应用程序,一个是用于填写手表的表格,数据正在通过 submitHandler 函数提交。第二部分是从应用程序的第一部分输入的手表。当我单击购买每只手表时,应将其添加到应用程序的第三部分,但限制是相同的手表(具有相同名称)只能添加一次 - 应该是唯一的,我应该通过应用程序,而不是启用添加到相同手表的第三部分。
下面是我的代码,其中包含 2 个函数,父函数 buyWatchHandler 正在调用 add 函数。buyWatchHandler 函数正在从 submitHandler 收集的表单字段中接收输入参数(观看详细信息),并且效果很好。在 buyWatchHandler 我让 arr 调用 add 函数,并且在 arr 变量中应该设置 add 函数的结果数组。当我们进入 add 函数时,输入的参数被很好地转发。在那里,我将 arr 设置为状态变量 this.state.selectedWatchList 的值。这里出现了问题。我正在对数组使用“some”方法来检查作为 selectedWatchName(input) 接收到的手表名称的值是否与 arr 的对象中的值相同,即 el.selectedWatchName。如果是,则返回 true,并且我不想转发调用函数。逻辑结果(真或假)设置为找到。如果 found 是假的,或者要清楚 - 元素的值与 arr(唯一手表)中的值不同,我想将 selectedWatchName 的值和 add 函数的其他输入参数的值连接到变量 arr . 在调用函数时,我们应该在 let arr 中接收转发的数组,并且应该将其添加到状态变量 selectedWatchList。
当我第一次在控制台中单击购买按钮时,发现的方法被打印为假,这是合乎逻辑的,因为 el.selectedWatchName 为空且与 selectedWatchName(input) 不同,添加函数中的 arr 打印为空且不应为空以及 buyWatchHandler 中的 this.state.selectedWatchList 被打印为空。在第二次单击 selectedWatchList 时填充了数据,发现是真的,这没关系,因为我正在尝试将相同的手表添加到 selectedWatchList 数组中。第三次点击应用程序崩溃,我不知道原因,任何人都可以发现什么问题,为什么会崩溃?警告如下:App.js:66 Uncaught TypeError: Cannot read property 'some' of undefined。购买按钮也应该在第三次点击和下一次点击时起作用,
import React, { Component } from 'react';
import EnteredWatches from '.././components/EnteredWatches/EnteredWatches';
class App extends Component {
constructor(props) {
super(props)
this.state = {
watchName: '',
watchDescription: '',
watchUrl: '',
watchPrice: '',
watchId: '',
enteredWatchList: [],
selectedWatchName: '',
selectedWatchDescription: '',
selectedWatchUrl: '',
selectedWatchPrice: '',
selectedWatchId: '',
selectedWatchList: []
}
}
submitHandler = (event) => {
event.preventDefault();
let watchId = Math.floor((Math.random() * 100) + 1);
let watchName = this.state.watchName;
let watchDescription = this.state.watchDescription;
let watchUrl = this.state.watchUrl;
let watchPrice = this.state.watchPrice;
this.setState({
enteredWatchList: this.state.enteredWatchList.concat({watchName, watchUrl, watchDescription, watchPrice, watchId})
})
console.log(this.state.enteredWatchList);
}
add = (selectedWatchName, selectedWatchUrl, selectedWatchDescription, selectedWatchPrice, index) => {
let arr = this.state.selectedWatchList;
let found = arr.some(el => {
return el.selectedWatchName === selectedWatchName;
});
console.log(found);
if (!found) {
return arr.concat({selectedWatchName, selectedWatchUrl, selectedWatchDescription, selectedWatchPrice, index});
}
console.log(arr);
}
buyWatchHandler = (selectedWatchName, selectedWatchUrl, selectedWatchDescription, selectedWatchPrice, index) => {
let arr = this.add(selectedWatchName, selectedWatchUrl, selectedWatchDescription, selectedWatchPrice, index);
this.setState({
selectedWatchName: selectedWatchName,
selectedWatchUrl: selectedWatchUrl,
selectedWatchDescription: selectedWatchDescription,
selectedWatchPrice: selectedWatchPrice,
selectedWatchId: index,
selectedWatchList: arr
});
console.log(this.state.selectedWatchList);
}
render() {
const enteredWatches = this.state.enteredWatchList.map((enteredWatch, index) => {
return <EnteredWatches
key={index}
enteredWatch={enteredWatch}
selected={this.buyWatchHandler.bind(this, enteredWatch.watchName, enteredWatch.watchUrl,
enteredWatch.watchDescription, enteredWatch.watchPrice, index)}
/>
});
return (
<div className="App">
<div className="container-fluid">
<div className="container">
<div className="add-product">
<form>
<div>
<label>Product name:</label>
<input
type="text"
placeholder="Casio Watch"
value={this.state.watchName.}
onChange={event => this.setState({watchName: event.target.value})}
/>
</div>
<div>
<label>Product description:</label>
<textarea
placeholder="Sample description..."
value={this.state.watchDescription}
onChange={event => this.setState({watchDescription: event.target.value})}
>
</textarea>
</div>
<div>
<label>Product image:</label>
<input
type="text"
placeholder="http://...jpg"
value={this.state.watchUrl}
pattern="https?://.+" required
onChange={event => this.setState({watchUrl: event.target.value})}
/>
</div>
<div>
<label>Product price:</label>
<input
type="number"
min="0"
placeholder="33.50"
value={this.state.watchPrice}
onChange={event => this.setState({watchPrice: event.target.value})}
/>
</div>
<button
type="submit"
onClick={event => this.submitHandler(event)}
>
Add a new Task
</button>
</form>
</div>
<div className="list-products">
<ul>
{enteredWatches}
</ul>
</div>
<div className="shopping-cart">
<div className="shopping-cart-products">
</div>
<div className="shopping-cart-summary">
<div>Total: <b>$429</b></div>
<div><button>Purchase</button></div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
解决方案
在您的 add 方法中,您只返回if(!found)
,但您的代码中的期望是该add()
方法将始终返回一个数组。
接下来,当add
没有显式return
JavaScript 时undefined
默认返回。最后,您将状态设置selectedWatchList
为 .. 的值,因此每当输入重复项时,arr
您都会.some()
尝试访问一个值。undefined
要解决此问题,该add
方法应始终返回this.selectedWatchList
给定条件if(found)
或作为else
当前代码中的 an。
推荐阅读
- reactjs - React、redux 和路由
- pdf - gopdf如何将文本数据打印成pdf?
- json - 如何在 Flutter 中解析地图列表时修复“.map.tolist() 返回实例而不是列表”?
- magento2 - Magento 2 Override by preference 在我的自定义模块中不起作用
- oracle - 如何修复此包体创建错误?
- payment - 有没有办法从 windows 10 将付款金额同步到信用卡终端,例如 verifone vx520 或 Ingenico ict250?
- java - 在多个黄瓜步骤定义中使用多个软断言时,黄瓜范围报告显示通过
- html - 使用表格单元格样式化 UL 的问题
- sql - 通过特定条件存在于 where 子句中的 SQL 验证
- amazon-web-services - 如何在 AWS DocumentDB 中编写 Join 查询