admin管理员组文章数量:1022543
I am trying to remove an element from an array when the onClick on the remove button is called, when the button is clicked I am getting Uncaught TypeError: Cannot read property 'name' of null
Why am I getting this error?
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>
)
}
I am trying to remove an element from an array when the onClick on the remove button is called, when the button is clicked I am getting Uncaught TypeError: Cannot read property 'name' of null
Why am I getting this error?
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>
)
}
Share
Improve this question
edited Mar 9, 2018 at 17:42
Omar
asked May 24, 2017 at 1:29
OmarOmar
3,4213 gold badges24 silver badges41 bronze badges
4
- 1 what is this ?... – cpugourou Commented May 24, 2017 at 1:32
-
Right now your code is failing on your
console.log('user.name);
. So something is wrong with yourthis.props.data[key]
which none of us could really be able to tell what it is. – Benjamin Commet Commented May 24, 2017 at 1:35 -
1
implies that
user
is null in{user.name}
– Jaromanda X Commented May 24, 2017 at 1:35 -
@cpugourou - looks like
react
– Jaromanda X Commented May 24, 2017 at 1:35
3 Answers
Reset to default 2Why am I getting this error?
You are explicitly setting data[key]
to null
:
data[key] = null;
When the ponent rerenders it presumably calls renderData
with the key that was "removed" (because the property is still there, its value is just null
). user
will be null
and accessing null.name
throws an error.
Depending on what you actually want, either skip null
values in your renderData
method, or actually delete the entry with
delete data[key];
Assigning null
does not delete a property:
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);
I am trying to remove an element from an array
If you really have an array, then there more things wrong. {...this.state.data}
is not an appropriate way to clone an array because you end up with an object.
To properly perform this action on an array you would do
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 });
}
Try:
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>
)
It seems like your data isn't ready when the ponent renders, so putting in a blank object will allow the ponent to render empty while the data loads.
edit: You could consider:
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>
)
This would hide the ponent as the data is being fetched. It's up to you then to municate that the data is loading to the user. You could pass down a loading
prop that is set to true when the request is fired and set to false when the request returns data and show either some loading text or an animation.
Removing objects from arrays
A good way to remove objects from arrays is to use filter. Using filter keeps us safe from bugs that e from using the index inside of the map function. data.map((item,index) => <div key={index} onClick={this.removeData(index)}> {item.fruit} </div>)
. This can cause serious problems when removing objects from the array.
What react says about this.
We don’t remend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with ponent state. Check out Robin Pokorny’s article for an in-depth explanation on the negative impacts of using an index as a key. If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
The Filter Approach
This approach takes whatever id the object has and returns every object that has a different id.
this.setState({ data: temp.filter(item => item.id !== id) });
Working Example
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'));
I am trying to remove an element from an array when the onClick on the remove button is called, when the button is clicked I am getting Uncaught TypeError: Cannot read property 'name' of null
Why am I getting this error?
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>
)
}
I am trying to remove an element from an array when the onClick on the remove button is called, when the button is clicked I am getting Uncaught TypeError: Cannot read property 'name' of null
Why am I getting this error?
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>
)
}
Share
Improve this question
edited Mar 9, 2018 at 17:42
Omar
asked May 24, 2017 at 1:29
OmarOmar
3,4213 gold badges24 silver badges41 bronze badges
4
- 1 what is this ?... – cpugourou Commented May 24, 2017 at 1:32
-
Right now your code is failing on your
console.log('user.name);
. So something is wrong with yourthis.props.data[key]
which none of us could really be able to tell what it is. – Benjamin Commet Commented May 24, 2017 at 1:35 -
1
implies that
user
is null in{user.name}
– Jaromanda X Commented May 24, 2017 at 1:35 -
@cpugourou - looks like
react
– Jaromanda X Commented May 24, 2017 at 1:35
3 Answers
Reset to default 2Why am I getting this error?
You are explicitly setting data[key]
to null
:
data[key] = null;
When the ponent rerenders it presumably calls renderData
with the key that was "removed" (because the property is still there, its value is just null
). user
will be null
and accessing null.name
throws an error.
Depending on what you actually want, either skip null
values in your renderData
method, or actually delete the entry with
delete data[key];
Assigning null
does not delete a property:
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);
I am trying to remove an element from an array
If you really have an array, then there more things wrong. {...this.state.data}
is not an appropriate way to clone an array because you end up with an object.
To properly perform this action on an array you would do
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 });
}
Try:
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>
)
It seems like your data isn't ready when the ponent renders, so putting in a blank object will allow the ponent to render empty while the data loads.
edit: You could consider:
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>
)
This would hide the ponent as the data is being fetched. It's up to you then to municate that the data is loading to the user. You could pass down a loading
prop that is set to true when the request is fired and set to false when the request returns data and show either some loading text or an animation.
Removing objects from arrays
A good way to remove objects from arrays is to use filter. Using filter keeps us safe from bugs that e from using the index inside of the map function. data.map((item,index) => <div key={index} onClick={this.removeData(index)}> {item.fruit} </div>)
. This can cause serious problems when removing objects from the array.
What react says about this.
We don’t remend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with ponent state. Check out Robin Pokorny’s article for an in-depth explanation on the negative impacts of using an index as a key. If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
The Filter Approach
This approach takes whatever id the object has and returns every object that has a different id.
this.setState({ data: temp.filter(item => item.id !== id) });
Working Example
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'));
本文标签:
版权声明:本文标题:Uncaught TypeError: Cannot read property of null, removing element from array javascript - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745562844a2156267.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论