代码在 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 !== "" &amp;&amp; &lt;p&gt;this.setState.message&lt;/p&gt;,应该是message !== "" &amp;&amp; &lt;p&gt;this.state.message&lt;/p&gt;

演示

完整代码:

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 !== "" &amp;&amp; &lt;p&gt;this.state.message&lt;/p&gt;,您有 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 的回调中,您将一个字段名称为emailref 对象分配给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 后无法在正常模式下运行

网站链接无法在 google chrome 上运行,但在 Firefox 上运行良好

为啥这段代码在 leetcode 运行良好,但在 geeksforgeeks 出现分段错误?