首页 > 解决方案 > 应用程序中断,警告 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;

标签: javascriptarraysreactjs

解决方案


在您的 add 方法中,您只返回if(!found),但您的代码中的期望是该add()方法将始终返回一个数组。

接下来,当add没有显式returnJavaScript 时undefined默认返回。最后,您将状态设置selectedWatchList为 .. 的值,因此每当输入重复项时,arr您都会.some()尝试访问一个值。undefined

要解决此问题,该add方法应始终返回this.selectedWatchList给定条件if(found)或作为else当前代码中的 an。


推荐阅读