首页 > 解决方案 > 如何使用 React 创建具有条件可编辑输入/单元格的表格?

问题描述

我有一张这样的桌子:

在此处输入图像描述

当用户点击一个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>不会消失。

标签: javascriptreactjshtml-tableconditional-statementsreact-state-management

解决方案


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

然后,当您单击一个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>


推荐阅读