【问题标题】:How can I create a table with conditionally editable input/cells using React?如何使用 React 创建具有条件可编辑输入/单元格的表格?
【发布时间】:2018-12-23 05:09:43
【问题描述】:

我有一张这样的桌子:

当用户点击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 按钮时,&lt;input&gt; 出现,但是当我点击另一个Edit 按钮时,之前的&lt;input&gt; 并没有消失。

【问题讨论】:

    标签: javascript reactjs html-table conditional-statements react-state-management


    【解决方案1】:

    如何使用最初设置为 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>

    【讨论】:

    • 谢谢@Danziger。您的解决方案正在按照我的要求工作。但你的returning 几乎是整张桌子。但我只想返回受影响的td。我认为国家正在制造问题。只有true 状态显示输出,但false 状态在这里不起作用。谢谢。
    • @abuabu 当你说 但我想只返回受影响的td 你的意思是你有另一个组件只呈现一个td 然后另一个呈现 table? 的组件
    • @abuabu 嘿,对不起,我在度假。我已更新代码以使用单独的组件和道具将其呈现为可编辑或不可编辑,并在进入编辑模式时向父组件发送事件。
    猜你喜欢
    • 1970-01-01
    • 2022-11-17
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多