未捕获的类型错误:使用 -http://localhost:8080/ 时无法读取 null- 的属性“length”
当我尝试使用 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>
);
}
>
您的初始状态是已定义的空数组,因此无需使用保护,因为对空数组进行长度检查 (
[].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
}
}
如评论中所述,上述方法有助于解决错误。
基本上,我们必须观察到 optionsArray 被声明/初始化为一个空数组。因此,当我们尝试查找其长度时,它显示为空,这不允许程序显示任何内容,从而引发错误。因此,为了解决这个问题,我们可以使用条件 JSX 方法,特别是逻辑 AND 运算符 (&&)。
{this.state.optionsArray && this.state.optionsArray.length > 0}
在这里,我们编写了 2 个语句进行比较。如果第一个语句为真(此处为“this.state.optionsArray”),它将执行第二个语句,因此我们将能够克服遇到 null 的问题。
由于我们使用空数组,因此稍后调试代码时必须遵循类似的方法。这种使用逻辑 AND 运算符的方法在遇到错误时非常有用,尤其是在这种情况下。
这是我在 StackOverflow 上的第一个答案,因此如果需要,请帮助改进答案。