简体   繁体   English

代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性”电子邮件“:Object 不可扩展”

[英]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 output in sandbox -->沙盒中的 output --> 沙箱输出

The error while running it in IDE -->在 IDE 中运行时的错误 --> ide错误

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回调中,您将一个字段名称为emailref 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.newDataobject是使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 链接:-

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 访问字段值。

  1. Initial state should be an empty array.初始 state 应该是一个空数组。

     this.state = { items: [], };
  2. The addData callback needs this of the class bound to it. addData回调需要绑定到它的 class 的this

  3. 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(); };
  4. 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" />
  5. 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>}

Demo演示

编辑-code-is-working-fine-in-codesandbox-but-showing-error-while-doing-in-the-id

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.

相关问题 未捕获的类型错误:无法定义属性“x”:对象不可扩展 - Uncaught TypeError: can't define property "x": Object is not extensible 类型错误:无法定义属性“当前”:Object 不可扩展 - TypeError: can't define property “current”: Object is not extensible React Error(TypeError):无法添加属性上下文,对象不可扩展 - React Error (TypeError): Can't add property context, object is not extensible 无法添加属性_tracking,对象不可扩展 - Can't add property _tracking, object is not extensible 无法定义属性“ _getObservable”:对象不可扩展 - Cannot define property '_getObservable': object is not extensible 未捕获的TypeError:无法添加属性12,对象不可扩展 - Uncaught TypeError: Can't add property 12, object is not extensible 无法在react中分配新属性,得到了“无法添加属性xxx,对象不可扩展” - Can not assign new property in react , got ` Can't add property xxx, object is not extensible` Node.js React:无法添加属性上下文,对象不可扩展 - Node.js React: Can't add property context, object is not extensible Vue.js中的对象不是可扩展错误 - object is not extensible error in vuejs 无法添加属性 2,对象不可扩展 Array.push - Can not add property 2, object is not extensible Array.push
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM