[英]The code is working fine in codeSandbox, But showing error while doing in the IDE as “can't define property ”email“: Object is not extensible”
I am trying to implement a simple code in react.js which user can input the data using form and unless the page is refreshed the data will show in the table.我正在尝试在 react.js 中实现一个简单的代码,用户可以使用表单输入数据,除非页面被刷新,否则数据将显示在表格中。
I have implemented a code in Code Sandbox and it worked as expected.我已经在 Code Sandbox 中实现了一个代码,它按预期工作。 Then I copied that code and used it in the IDE.
然后我复制了该代码并在 IDE 中使用它。 Now the same code is showing error as ==> "TypeError: can't define property "email": Object is not extensible".
现在相同的代码显示错误==>“TypeError:无法定义属性“email”:Object 不可扩展”。 (I am using intellij IDE ultimate edition)
(我使用的是 intellij IDE 终极版)
This is the link for sandbox => Link for the code in sandbox这是沙盒的链接 => 沙盒中代码的链接
The code it self if the sand box is not working ==>如果沙盒不工作,它自己的代码 ==>
import React, {Component} from "react";
class CustomDetails extends Component {
constructor(props) {
super(props);
this.state = {
items: [{email: '', country: '', new_case: '', total_case: '', total_death: ''}],
message: ''
}
this.newData = React.createRef();
this.addForm = React.createRef();
}
addData(e) {
e.preventDefault();
const {items} = this.state;
const newData = () => ({
email:this.addForm.email.value,
country:this.addForm.country.value,
new_case:this.addForm.new_case.value,
total_case:this.addForm.total_case.value,
total_death:this.addForm.total_death.value
})
const isOnTheList = items.includes(newData.country);
if (isOnTheList) {
this.setState(({
message: 'This country details are already added.'
}))
} else {
this.setState({
items: [...this.state.items, newData()],
})
}
this.addForm.reset();
}
render() {
const {items, message}=this.state;
return (
<div>
<div>
<div>
<form ref={input => this.addForm = input} onSubmit={(e) => {
this.addData(e)
}}>
<label>User Email :</label><br/>
<input required ref={input => this.newData["email"] = input} name="email" value={this.state.items.email}
type="email"
placeholder="Enter email"/><br></br>
<label>Country :</label><br/>
<input required ref={input => this.newData["country"] = input} name="country" value={this.state.items.country}
type="text"
placeholder="Enter country"/><br></br>
<label>New Cases :</label><br/>
<input required ref={input => this.newData["new_case"] = input}
name="new_case"
value={this.state.items.new_case} type="text"
placeholder="Enter no of new cases"/><br></br>
<label>Total cases :</label><br/>
<input required ref={input => this.newData["total_case"] = input}
name="total_case"
value={this.state.items.total_case} type="text"
placeholder="Enter no of total cases"/><br></br>
<label>Total death :</label><br/>
<input required ref={input => this.newData["total_death"] = input}
name="total_death"
value={this.state.items.total_death} type="text"
placeholder="Enter no of total deaths"/><br></br>
<button variant="primary" type="submit">
Submit</button><br></br>
</form>
</div>
<div>
{
message !== '' && <p>{this.setState.message}</p>
}
<table striped="true" bordered="true" hover="true">
<thead>
<tr>
<th>Email</th>
<th>Country</th>
<th>New cases</th>
<th>Total cases</th>
<th>Total deaths</th>
</tr>
</thead>
<tbody>
{items.map((item,index) => {
return (
<tr key={index}>
<td>{item.email}</td>
<td>{item.country}</td>
<td>{item.new_case}</td>
<td>{item.total_case}</td>
<td>{item.total_death}</td>
</tr>
)
})}
</tbody>
</table>
</div>
</div>
</div>
)
}}export default CustomDetails;
The culprit is the below line (and if you remove it, it will be the next input
line):-罪魁祸首是下面的行(如果你删除它,它将是下一个
input
行): -
<input required ref={input => this.newData["email"] = input} name="email" value={this.state.items.email} type="email" placeholder="Enter email"/><br></br>
In your ref
's callback, you are assigning a ref
object with a field name of email
to input
.在您的
ref
回调中,您将一个字段名称为email
的ref
object 分配给input
。
If you go ahead and console.log(Object.isExtensible(this.newData)
in your render
method, you will see it will show false
. So you're trying to add an email
property to an object
which doesn't allow it. Your codesandbox is silently failing but your IDE is running in strict mode .如果您提前 go 和
console.log(Object.isExtensible(this.newData)
在您的render
方法中,您将看到它将显示false
。因此您尝试将email
属性添加到object
不允许它。您的代码盒静默失败,但您的IDE正在以严格模式运行。
You need to initialize this.newData
to an object
by making this.newData
equivalent to {email: '', country: '', new_case: '', total_case: '', total_death: ''};
您需要将 this.newData 初始化为
this.newData
, object
是使this.newData
等同于{email: '', country: '', new_case: '', total_case: '', total_death: ''};
as per your use-case.根据您的用例。 So your
this.newData
will not be a React ref
anymore but just an instance variable for your Class.因此,您的
this.newData
将不再是 React ref
,而只是您的 Class 的实例变量。
Here are MDN links that helped:-以下是帮助的 MDN 链接:-
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
Do see @Drew's answer on how to deal with inputs in a better way.请参阅@Drew 关于如何以更好的方式处理输入的答案。
There really isn't a point to using React refs in this case as you can easily access the field values from the form's onSubmit
event object.在这种情况下使用 React refs 确实没有意义,因为您可以轻松地从表单的
onSubmit
事件 object 访问字段值。
Initial state should be an empty array.初始 state 应该是一个空数组。
this.state = { items: [], };
The addData
callback needs this
of the class bound to it. addData
回调需要绑定到它的 class 的this
。
addData
should access the form field values from the onSubmit
event object. addData
应该从onSubmit
事件 object 访问表单字段值。 The newData
should be an object of the form field values you want to push into your items
state array. newData
应该是您要推送到items
state 数组中的表单字段值的 object。 Use a functional state update to update from the previous state.使用功能性 state 更新从以前的 state 更新。 When searching the
items
array for existing entries you need to use an array function that allows examining object properties as Array.prototype.includes
really only check reference equality, you want to search for an item that has a matching country
property using Array.prototype.some
to return a boolean.在为现有条目搜索
items
数组时,您需要使用数组 function 允许检查 object 属性,因为Array.prototype.includes
实际上只检查引用相等性,您想使用 Array.prototype 搜索具有匹配country
属性的项目Array.prototype.some
返回 boolean。
addData = (e) => { e.preventDefault(); const { items } = this.state; const newData = { email: e.target.email.value, country: e.target.country.value, new_case: e.target.new_case.value, total_case: e.target.total_case.value, total_death: e.target.total_death.value }; const isOnTheList = items.some(item => item.country === newData.country); if (isOnTheList) { this.setState({ message: "This country details are already added." }); } else { this.setState((prevState) => ({ items: [...prevState.items, newData] })); } e.target.reset(); };
Since you've uncontrolled inputs you should remove the old "legacy" style ref attachments and value
prop.由于您有不受控制的输入,因此您应该删除旧的“遗留”样式 ref 附件和
value
道具。 Example:例子:
<input required name="email" type="email" placeholder="Enter email" />
You've a typo when trying to render an error message, {message.== "" && <p>{this.setState.message}</p>}
, it should be {message.== "" && <p>{this.state.message}</p>}
.您在尝试呈现错误消息时打错了
{message.== "" && <p>{this.setState.message}</p>}
,它应该是{message.== "" && <p>{this.state.message}</p>}
。
Full code:完整代码:
class CustomDetails extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
message: ""
};
}
addData = (e) => {
e.preventDefault();
const { items } = this.state;
const newData = {
email: e.target.email.value,
country: e.target.country.value,
new_case: e.target.new_case.value,
total_case: e.target.total_case.value,
total_death: e.target.total_death.value
};
const isOnTheList = items.includes(newData.country);
if (isOnTheList) {
this.setState({
message: "This country details are already added."
});
} else {
this.setState((prevState) => ({
items: [...prevState.items, newData]
}));
}
e.target.reset();
};
render() {
const { items, message } = this.state;
return (
<div>
<div>
<div>
<form onSubmit={this.addData}>
<label>User Email :</label>
<br />
<input
required
name="email"
type="email"
placeholder="Enter email"
/>
<br></br>
<label>Country :</label>
<br />
<input
required
name="country"
type="text"
placeholder="Enter country"
/>
<br></br>
<label>New Cases :</label>
<br />
<input
required
name="new_case"
type="text"
placeholder="Enter no of new cases"
/>
<br></br>
<label>Total cases :</label>
<br />
<input
required
name="total_case"
type="text"
placeholder="Enter no of total cases"
/>
<br></br>
<label>Total death :</label>
<br />
<input
required
name="total_death"
type="text"
placeholder="Enter no of total deaths"
/>
<br></br>
<button variant="primary" type="submit">
Submit
</button>
<br></br>
</form>
</div>
<div>
{message !== "" && <p>{this.state.message}</p>}
<table striped="true" bordered="true" hover="true">
<thead>
<tr>
<th>Email</th>
<th>Country</th>
<th>New cases</th>
<th>Total cases</th>
<th>Total deaths</th>
</tr>
</thead>
<tbody>
{items.map((item, index) => {
return (
<tr key={index}>
<td>{item.email}</td>
<td>{item.country}</td>
<td>{item.new_case}</td>
<td>{item.total_case}</td>
<td>{item.total_death}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.