如何在React中为特定项目创建唯一的编辑字段

时间:2019-01-28 05:10:30

标签: reactjs

来自标题本身。我在React中学习新知识,并且在编辑字段方面遇到问题。

每当我单击要编辑的特定项目时,未选择的其余项目也会被编辑,如下屏幕所示。我想知道如何生成唯一的编辑字段框,这些框只能编辑当前选定的特定字段。每次我在editedField上输入新项目时,都会出现这种错误。

enter image description here

代码

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Skills extends Component {
    constructor(props) {
        super(props);

        this.state = { 
            skills : ["Frost Bolt", "Arcane Missle"],
            skillField : '',
            skiller : '',
            editIsHidden : true,
            editConfIsHidden : true,
            editSkillField : '',
        };

        // Event Listeners
        this.addSkill = this.addSkill.bind(this);
        this.removeSkill = this.removeSkill.bind(this);
        this.editSkill = this.editSkill.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.clearField = this.clearField.bind(this);
        this.confirmEdit = this.confirmEdit.bind(this);
    }

    clearField() {
        this.setState({
            skillField : ''
        });
    }

    handleChange(event, element) {
        this.setState({
            [element] : event.target.value
        });
    }

    editSkill(editedSkill) {

        this.setState({
            editIsHidden : false
        });

        this.setState({
            editConfIsHidden : false
        });
    }

    confirmEdit(oldEditedSkill) {
        let index = 0;
        let skillsArray = this.state.skills;
        let newEditedSkill = this.state.editSkillField;

        this.state.skills.forEach(function(skill) {
            if (skill == oldEditedSkill) {
                skillsArray[index] = newEditedSkill;
                console.log(newEditedSkill);
            }
            index++;
        });

        this.setState({
            skills : skillsArray
        });

        this.setState({
            editConfIsHidden : true
        });

        this.setState({
            editIsHidden : true
        });

        console.log(this.state.skills);
    }

    addSkill() {
        this.state.skills.push(this.state.skillField);
        this.setState({
            skills: this.state.skills
        });
        console.log(this.state.skills);
        this.clearField();
    }

    removeSkill(removedSkill) {
        let adr = 0;
        let skillsArray = this.state.skills;

        this.state.skills.forEach(function(skill) {
            if (skill == removedSkill) {
                skillsArray.splice(adr, 1); 
            }
            adr++;
        });

        this.setState({
            skills : skillsArray
        });
    }

    render() {
        const skillLists = this.state.skills.map((val) => {
            return  <li>{val}
                        <input onChange={(e) => this.handleChange(e, "editSkillField")} value={this.state.editSkillField} className={this.state.editIsHidden ? 'hidden' : ''} />
                        <button onClick={() => this.removeSkill(val)}>x</button>
                        <button onClick={() => this.editSkill(val)}>e</button>
                        <button onClick={() => this.confirmEdit(val)} className={this.state.editConfIsHidden ? 'hidden' : ''} >ok</button>
                    </li>
        });
        return (
            <div>
                <input onChange={(e) => this.handleChange(e, "skillField")} value={this.state.skillField} />
                <button onClick={this.addSkill}>Add Skill</button>
                <h4>Skills</h4>
                <ul>{skillLists}</ul>
            </div>
        );
    }
}

export default Skills;

2 个答案:

答案 0 :(得分:1)

如果您仔细查看skills所映射的代码,就会发现列表中的每个项目都启用或禁用了className hidden,如下面的代码。

<input onChange={(e) => this.handleChange(e, "editSkillField")} value= {this.state.editSkillField} className={this.state.editIsHidden ? 'hidden' : ''} />

我们首先需要有一个状态,告知有问题的特定字段是可编辑的。您可以根据自己的需求以多种方式完成此操作。这是一种方法。

您的editSkill函数必须存储要编辑的skill。下面的方法会起作用。

editSkill(editedSkill) {
 this.setState({
  editIsHidden : editedSkill
 });

 this.setState({
  editConfIsHidden : editedSkill
 });
}

然后,您的渲染将进行如下所示的修改

const skillLists = this.state.skills.map((val) => {
 return  <li>{val}
          <input onChange={(e) => this.handleChange(e, "editSkillField")} value={this.state.editSkillField} className={(this.state.editIsHidden !== val) ? 'hidden' : ''} />
          <button onClick={() => this.removeSkill(val)}>x</button>
          <button onClick={() => this.editSkill(val)}>e</button>
          <button onClick={() => this.confirmEdit(val)} className={(this.state.editConfIsHidden !== val) ? 'hidden' : ''} >ok</button>
         </li>
});

然后在您的confirmEdit函数中,重置各个状态变量的值,例如

 this.setState({
  editConfIsHidden : null,
 });

 this.setState({
  editIsHidden : null,
 });

这将帮助您解决问题。但是,应该考虑的事情很少。

  1. 尝试维护较少的状态。我希望状态editConfIsHiddeneditIsHidden可以被一个状态代替,除非您有特定的用例来单独使用它们。

  2. 当我们尝试设置状态时,我们可以使用对this.setState的单个调用,而不是此答案中所示的连续和多个setState

答案 1 :(得分:0)

您应该考虑以这种方式将其更改为对象,这样就可以轻松处理它,而不必维护其他属性。

skills: [{ id: "Frost Bolt", value: '' }, { id: "Arcane Missle", value: '' }],

当输入更改尝试像这样更改时

  handleChangeSkills(event, element) {
    this.setState({
      skills: this.state.skills.map(a => {
        if (a.id === element) {
          a.value = event.target.Value;
        }
        return a;
      })
    });
  }

保留您的handlechange

  handleChange(event, element) {
    this.setState({
      [element]:event.target.value
    });
  }

并在这样的技能输入中称呼它

 <input onChange={(e) => this.handleChangeSkills(e, val.id)} 
value={val.val} className={this.state.editIsHidden ? 'hidden' : ''} />

这里是demo