开发者问题收集

未捕获的类型错误:使用 -http://localhost:8080/ 时无法读取 null- 的属性“length”

2020-07-25
1342

当我尝试使用 live-server 和 http://127.0.0.1:8080/ 运行以下代码 (IndecisionApp.js) 时,代码很好地显示了输出。但我安装了 3.1.0 版的 webpack、3.3.12 版的 webpack-cli 和 2.5.1 版的 webpack-dev-server。但是当使用 yarn run webpack-dev-server 在 http://localhost:8080/ 上运行 webpack-dev-server 时,它显示了错误: Uncaught TypeError: Cannot read property 'length' of null at ...

基本上,optionsArray 数组在加载时被称为 null。在渲染中发现 Action 标签的 handleOptions 属性存在问题。我看到的一个答案建议使用 try-catch 方法,但错误仍然存​​在。请帮助我解决此错误,因为屏幕上没有显示任何内容

错误控制台

代码:

import React from 'react';
...
import Action from "./Action";

export default class IndecisionApp extends React.Component {
constructor(props){
    super(props);

    this.state = {
        optionsArray: []
    }

    this.handleDeleteOptions = this.handleDeleteOptions.bind(this)
    this.handlePick = this.handlePick.bind(this);
    this.handleAddOptions = this.handleAddOptions.bind(this);
    this.handleDeleteSingleOption = this.handleDeleteSingleOption.bind(this);
    
}

componentDidMount(){
    try {
        const json = localStorage.getItem('options');
        const options = JSON.parse(json);

        this.setState(() => ({ optionsArray: options }));
    }
    catch(e) {
        // Do nothing
    }
    
}

componentDidUpdate(prevProps, prevState){                   
    // Saving Data to local storage
    if(prevState.optionsArray.length !== this.state.optionsArray.length){
        const json = JSON.stringify(this.state.optionsArray);
        localStorage.setItem('options', json);
    }
}

handleDeleteOptions(){
    this.setState(() => ({ optionsArray: [] }));
}

handleDeleteSingleOption(optionToRemove){
    this.setState((prevState) => ({
        optionsArray: prevState.optionsArray.filter((option) => {
            return (optionToRemove !== option)                      // Returns true or false, since filter method is being used
        })
    }));
}

handlePick(){
    const randomNum = Math.floor(Math.random() * this.state.optionsArray.length);
    const option = this.state.optionsArray[randomNum];
    alert(option);
}

handleAddOptions(option){
    // Validation of string input for adding item
    if(!option){
        return 'Enter valid value to add item'
    }
    else if(this.state.optionsArray.indexOf(option) > -1){
        return 'This option already exsits'
    }

    this.setState((prevState) => ({ optionsArray: prevState.optionsArray.concat(option) }));
}

render(){
    const subtitle = 'Assisting you to take your decisions';

    return(
        <div>
            <Header subtitle={subtitle} />

            <Action 
                hasOptions={this.state.optionsArray.length > 0} 
                handlePick={this.handlePick}
            />

            <Options 
                options={this.state.optionsArray} 
                handleDeleteOptions={this.handleDeleteOptions} 
                handleDeleteSingleOption={this.handleDeleteSingleOption}
            />

            <AddOption  
                options={this.state.optionsArray} 
                handleAddOptions={this.handleAddOptions}
            />  
        </div>
    );
}

>

2个回答

您的初始状态是已定义的空数组,因此无需使用保护,因为对空数组进行长度检查 ( [].length ) 是完全有效且足够的。

console.log([].length);

正如我在评论中问到的,似乎有 某些东西 正在改变您的状态,或者将其更新为 其他 空数组。如果在获取 localStorage.getItem('options') 时没有存储“options”键值,则返回 null 。然后你用 JSON 解析它,它也会返回 null,然后你用 null 值更新你的状态。

const json = localStorage.getItem('options'); // possibly null
const options = JSON.parse(json); // returns null if json === null

this.setState(() => ({ optionsArray: options })); // just possibly stored null

这在 SO 中不起作用,但请在你自己的控制台中尝试

const json = localStorage.getItem('dEfInItElYpRoBaBlYnOtAkEy'); // null
JSON.parse(json); // null

你应该检查从 localStorage 获取的结果

const json = localStorage.getItem('options');
if (json) {
  // truthy and exists (i.e. not null or undefined)
  try {
    const options = JSON.parse(json);
    this.setState(() => ({ optionsArray: options }));
  } catch(err) {
    // handle error, likely from bad JSON parsing
  }
}
Drew Reese
2020-07-25

如评论中所述,上述方法有助于解决错误。

基本上,我们必须观察到 optionsArray 被声明/初始化为一个空数组。因此,当我们尝试查找其长度时,它显示为空,这不允许程序显示任何内容,从而引发错误。因此,为了解决这个问题,我们可以使用条件 JSX 方法,特别是逻辑 AND 运算符 (&&)。

{this.state.optionsArray && this.state.optionsArray.length > 0}

在这里,我们编写了 2 个语句进行比较。如果第一个语句为真(此处为“this.state.optionsArray”),它将执行第二个语句,因此我们将能够克服遇到 null 的问题。

由于我们使用空数组,因此稍后调试代码时必须遵循类似的方法。这种使用逻辑 AND 运算符的方法在遇到错误时非常有用,尤其是在这种情况下。

这是我在 StackOverflow 上的第一个答案,因此如果需要,请帮助改进答案。

Aniruddh Muley
2020-07-25