我如何使用 React 创建一个有条件的 editable input/cells table?

How can I create a table with conditionally editable input/cells using React?

我有一个 table 这样的:

当用户点击 Edit 按钮时,<input> 应该出现在它的位置。

如果用户点击另一个 Edit 按钮,这个按钮也将被替换为 <input>,并且之前的 <input> 应该消失并显示 Edit再次按钮。

简而言之,一次只能有一个字段处于编辑模式。

这是我的首字母state:

state = {
    editnameEnable: false,
    editemailEnable: false,
    editaddressEnable: false,
    edittelephone_noEnable: false,
}

这是我的edit()方法:

edit = value => {
    var address_element = ['name','address','email','telephone_no']; 
    address_element = address_element.filter(element => element !== value); 
    address_element.map( val => this.setState({[`edit${val}Enable`]: false}));

    this.setState({[`edit${value}Enable`]: true}, ()=>{
        console.log(this.state);
    });
}

这是我的 render 方法中 JSX 的一部分:

<td>{
    this.state[`edit${this.props.item}Enable`] ? ( <input type="text"/> ) : (
        <span
            className="edit"
            onClick={ () => this.edit(this.props.item) }>Edit</span>
    )
}</td>

问题是当我点击一个Edit按钮时,<input>出现,但是当我点击另一个Edit按钮时,之前的<input>没有出现消失。

使用初始设置为 null 的单个 editableField 属性 怎么样?

然后,当您单击 Edit 按钮时,将 editableField 设置为该字段的名称,并在 render 中检查每个字段是否 editableField 匹配或不匹配其名称以呈现 Edit 按钮或输入字段。

像这样:

class FieldCell extends React.Component {

  constructor(props) {
    super(props);
  }
  
  focusField = (element) => element && element.focus();
  
  render() {
    const editElement = this.props.isEditable ? (
      <input type="text" ref={ this.focusField }/>
    ) : (
      <button onClick={ () => this.props.onEdit() }>EDIT</button>
    );
    
    return (<td className="textLeft">{ editElement }</td>);
  }
}

class UserData extends React.Component {

  constructor(props) {
    super(props);
    
    this.state = {
      editableField: null,
    };
  }
  
  render() {
    const editableField = this.state.editableField;
    
    const rows = ['Name', 'Address', 'Telephone No.', 'E-Mail'].map((field) => {
      const isEditable = field === editableField;
      
      return (
        <tr key={ field }>
          <td>{ field }</td>
          <FieldCell isEditable={ isEditable } onEdit={ () => this.setState({ editableField: field })}></FieldCell>
        </tr>
      );
    });

    return (<table>{ rows }</table>);
  }
}

ReactDOM.render(<UserData />, document.getElementById('app'));
body {
  font-family: monospace;
  font-size: 13px;
}

table {
  border: 2px solid #000;
  border-collapse: collapse;
  text-align: right;
  width: 100%;
}

td {
  border: 2px solid #000;
  padding: 4px;
  width: 50%;
  overflow: hidden;
}

.textLeft {
  text-align: left;
  user-select: none;
}

button,
input {
  border: 2px solid black;
  padding: 4px 8px;
  margin: 0;
  font-family: monospace;
  font-size: 13px;
  box-sizing: border-box;
  background: none;
  outline: none;
}

button:hover,
button:focus,
input:hover,
input:focus {
  border-color: blue;
  color: blue;
}

button {
  font-weight: bold;
}

input {
  width: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>