代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性“电子邮件”:对象不可扩展”
Posted
技术标签:
【中文标题】代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性“电子邮件”:对象不可扩展”【英文标题】: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" 【发布时间】:2021-06-15 12:01:45 【问题描述】:我正在尝试在 react.js 中实现一个简单的代码,用户可以使用表单输入数据,除非页面被刷新,否则数据将显示在表格中。
我已经在 Code Sandbox 中实现了一个代码,它按预期工作。然后我复制了该代码并在 IDE 中使用它。现在相同的代码显示错误==>“TypeError:无法定义属性“电子邮件”:对象不可扩展”。 (我用的是intellij IDE终极版)
这是沙盒的链接 => Link for the code in sandbox
如果沙盒不工作,它自己的代码 ==>
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;
沙盒中的输出 -->
在 IDE 中运行时的错误 -->
【问题讨论】:
this.state.items
是数组而不是对象使用:this.state.items[0].email
或将this.state.items
更改为对象
试过了..但得到同样的错误。但是上面的代码在沙箱中运行良好
更改constructor
:this.newData = email: '', country: '', new_case: '', total_case: '', total_death: '';
和this.addForm = email: '', country: '', new_case: '', total_case: '', total_death: '';
【参考方案1】:
在这种情况下使用 React refs 确实没有意义,因为您可以轻松地从表单的 onSubmit
事件对象访问字段值。
初始状态应该是一个空数组。
this.state =
items: [],
;
addData
回调需要绑定到它的类的this
。
addData
应该从onSubmit
事件对象访问表单字段值。 newData
应该是您要推送到 items
状态数组中的表单字段值的对象。使用功能状态更新从之前的状态进行更新。在 items
数组中搜索现有条目时,您需要使用允许检查对象属性的数组函数,因为 Array.prototype.includes
实际上只检查引用相等性,您希望使用 @987654335 搜索具有匹配 country
属性的项目@ 返回一个布尔值。
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();
;
由于您的输入不受控制,您应该删除旧的“遗留”样式参考附件和value
属性。示例:
<input
required
name="email"
type="email"
placeholder="Enter email"
/>
您在尝试呈现错误消息时打错了message !== "" && <p>this.setState.message</p>
,应该是message !== "" && <p>this.state.message</p>
。
演示
完整代码:
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>
);
【讨论】:
非常感谢您的最佳解释。为了只向国家名称添加 1 个数据,当用户为同一国家/地区输入另一个数据时,我添加了一条错误消息。我为了得到该消息需要将键值替换为 item.country 吗? @Deepika 完全正确,.includes
数组函数不适用于对象属性,我建议使用 .some
检查 some 项是否有匹配的 @ 987654344@ 属性值。我更新了我的答案并链接了代码框。刚刚注意到您在尝试呈现消息时还有一个类型,它是 message !== "" && <p>this.state.message</p>
,您有 this.setState.message
。
非常感谢。从这个解释中,我能够理解代码以及我做错了什么。
如果我想计算 new_cases、total_cases 和 total_deaths 的总数(如果 4 使用输入数据计算以下 4 个数据),并通过创建新列将它们添加到表中怎么做使用功能? @德鲁
@Deepika codesandbox.io/s/…【参考方案2】:
罪魁祸首是下面一行(如果你删除它,它将是下一个input
行):-
<input required ref=input => this.newData["email"] = input name="email" value=this.state.items.email type="email" placeholder="Enter email"/><br></br>
在您的ref
的回调中,您将一个字段名称为email
的ref
对象分配给input
。
如果您继续在您的render
方法中使用console.log(Object.isExtensible(this.newData)
,您会看到它将显示false
。因此,您尝试将 email
属性添加到不允许的 object
中。
您的 codesandbox 静默失败,但您的 IDE 正在严格模式下运行。
您需要根据您的用例将this.newData
等同于email: '', country: '', new_case: '', total_case: '', total_death: '';
,将this.newData
初始化为object
。因此,您的 this.newData
将不再是 React ref
,而只是您的 Class 的实例变量。
这里是帮助的 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/Global_Objects/Object/isExtensible
请参阅@Drew 关于如何以更好的方式处理输入的答案。
【讨论】:
以上是关于代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性“电子邮件”:对象不可扩展”的主要内容,如果未能解决你的问题,请参考以下文章
我的 Javascript 代码在 IE 中无法运行,但在其他浏览器中运行良好
DBUS 代码在放置在守护进程中时崩溃,但在没有守护进程代码的独立独立 main() 函数中运行良好
代码在我的计算机上运行良好,但在“hackerearth”平台上在线运行时出现 NullPointerException
VBA Excel 在调试中运行良好,但在安全更新 KB4022174 后无法在正常模式下运行