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

问题描述

我正在尝试在 react.js 中实现一个简单的代码用户可以使用表单输入数据,除非刷新页面,否则数据将显示在表格中。

我在 Code SandBox 中实现了一个代码,它按预期工作。然后我复制了该代码并在 IDE 中使用它。现在相同的代码显示错误为 ==> "TypeError: can't define property "email": Object is not extensible"。 (我用的是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;

沙箱中的输出-->

Sand box output

在IDE中运行时出错-->

ide error

解决方法

罪魁祸首是下面的行(如果你删除它,它将是下一个 input 行):-

<input required ref={input => this.newData["email"] = input} name="email" value={this.state.items.email} type="email" placeholder="Enter email"/><br></br>

ref 的回调中,您将字段名称为 refemail 对象分配给 input

如果您继续在 console.log(Object.isExtensible(this.newData) 方法中使用 render,您会看到它会显示 false。因此,您试图将 email 属性添加到不允许它的 object。 您的 codesandbox 正在默默地失败,但您的 IDE 正在严格模式下运行。

您需要根据您的用例将 this.newData 初始化为 object,方法是将 this.newData 等同于 {email: '',country: '',new_case: '',total_case: '',total_death: ''};。因此,您的 this.newData 将不再是 React ref,而只是您的类的实例变量。

这里有帮助的 MDN 链接:-

请参阅@Drew 关于如何以更好的方式处理输入的回答。

,

在这种情况下确实没有必要使用 React refs,因为您可以轻松地从表单的 onSubmit 事件对象访问字段值。

  1. 初始状态应该是一个空数组。

    this.state = {
      items: [],};
    
  2. addData 回调需要绑定到它的类的 this

  3. addData 应该从 onSubmit 事件对象访问表单字段值。 newData 应该是您想要推入 items 状态数组的表单字段值的对象。使用功能状态更新从之前的状态进行更新。在 items 数组中搜索现有条目时,您需要使用允许检查对象属性的数组函数,因为 Array.prototype.includes 实际上只检查引用相等性,您希望搜索具有匹配 {{1 }} 属性使用 country 返回布尔值。

    Array.prototype.some
  4. 由于您有不受控制的输入,您应该删除旧的“遗留”样式参考附件和 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
  5. 您在尝试呈现错误消息时打错了 <input required name="email" type="email" placeholder="Enter email" /> ,它应该是 {message !== "" && <p>{this.setState.message}</p>}

演示

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

完整代码:

{message !== "" && <p>{this.state.message}</p>}