未捕获的TypeError:无法读取null的属性,从数组javascript中删除元素

时间:2017-05-24 01:29:58

标签: javascript

我试图在调用onClick on the remove按钮时从数组中删除元素,当单击按钮时我得到未捕获TypeError:无法读取属性' name'为null

为什么我收到此错误?

removeData(key) {
  console.log(key);
  const data = this.state.data;
  data[key] = null;
  this.setState({ data });
}

renderData(key){
    const user = this.props.data[key];
    console.log(user.name);
    console.log(user.id);
    return(
      <div key={key}>
          <li>  <strong> Name: </strong>  {user.name},
          <strong>  ID: </strong> {user.id} </li>
          <button onClick={() => this.props.removeData(key)}> Remove </button>
      </div>
    )
}

3 个答案:

答案 0 :(得分:1)

  

为什么我收到此错误?

您明确将data[key]设置为null

data[key] = null;

当组件重新呈现时,可能会使用“已删除”的键调用renderData(因为该属性仍然存在,其值仅为null)。 user将为null,访问null.name会引发错误。

根据您的实际需要,您可以在null方法中跳过renderData值,或者删除条目

delete data[key];

分配null 删除属性

var obj = {foo: 42};

// Doesn't actually remove the property
obj.foo = null;
console.log(obj);

// This removes the property
delete obj.foo;
console.log(obj);

  

我正在尝试从数组中删除元素

如果你真的有一个数组,那么就会出现更多错误。 {...this.state.data}不是克隆数组的合适方法,因为您最终会得到对象

要在阵列上正确执行此操作

removeData(key) {
  // Assuming `key` is the index of the element
  // Create copy
  const data = Array.from(this.state.data);
  // Remove element at index `key`
  data.splice(key, 1);
  this.setState({ data });
}

答案 1 :(得分:0)

尝试:

renderData(key){
    const user = this.props.data[key] || {}; // change
    console.log(user.name);
    console.log(user.id);
    return(
      <div key={key}>
          <li>  <strong> Name: </strong>  {user.name},
          <strong>  ID: </strong> {user.id} </li>
          <button onClick={() => this.props.removeData(key)}> Remove </button>
      </div>
    )

当组件呈现时,您的数据似乎还没有准备好,因此放入一个空白对象将允许组件在数据加载时呈现为空。

编辑:您可以考虑:

renderData(key){
        if (!this.props.data[key]) return null; //change
        const user = this.props.data[key];
        console.log(user.name);
        console.log(user.id);
        return(
          <div key={key}>
              <li>  <strong> Name: </strong>  {user.name},
              <strong>  ID: </strong> {user.id} </li>
              <button onClick={() => this.props.removeData(key)}> Remove </button>
          </div>
        )

这会在获取数据时隐藏组件。然后由您决定将数据加载到用户。您可以传递一个loading道具,当请求被触发时设置为true,当请求返回数据并显示一些加载文本或动画时设置为false。

答案 2 :(得分:0)

从数组中删除对象

从数组中删除对象的好方法是使用过滤器。使用过滤器可以保护我们免受来自使用map函数内部索引的错误的影响。 data.map((item,index) => <div key={index} onClick={this.removeData(index)}> {item.fruit} </div>)。从阵列中删除对象时,这可能会导致严重问题。

对此有何反应。

  

如果商品的订单可能,我们不建议使用密钥索引   更改。这可能会对性能产生负面影响,并可能导致问题   与组件状态。查看Robin Pokorny的文章   深入解释使用指数作为负面影响的负面影响   键。如果您选择不为列出项目分配显式键,则   React将默认使用索引作为键。

过滤方法

此方法接受对象具有的任何id,并返回具有不同id的每个对象。

this.setState({ data: temp.filter(item => item.id !== id) });

工作示例

import React, { Component } from 'react';
import { render } from 'react-dom'; 
class App extends Component {
  constructor() {
    super();
        this.state = { 
     data:[
     { fruit: "apple", id:1 },
     { fruit: "orange", id:2 }, 
     { fruit: "pineapple", id:3 },
    ],
    }
  }
      removeData = (id) => {
      const { data } = this.state;  
      const temp = data.slice();  
      this.setState({ data: temp.filter(item => item.id !== id) });
    }
    renderData = () =>{
        const { data } = this.state;
        return data.map((item) => {
         return  <div key={item.id}>
         <label> {item.fruit} </label>
         {item.id}
         <button onClick={() => this.removeData(item.id)}> Remove </button>
         </div>         
        })     
    }
  render() {
    return (
      <div>
        {this.renderData()}
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));