【问题标题】:Change of textarea in a table generated by React not working properlyReact 生成的表格中的文本区域更改无法正常工作
【发布时间】:2018-06-21 10:17:47
【问题描述】:

我准备了一个小演示:https://codepen.io/anon/pen/mKxPaB?editors=0010

class List extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rows: [{ text: "first" }, { text: "second" }]
    };

    this.addNewRow = this.addNewRow.bind(this);
  }

  renderTableRow(t, index) {
    return <Row key={index} {...t} />;
  }

  addNewRow() {
    this.setState(prevState => {
      const rowsCopy = prevState.rows.slice();
      return { rows: [{ text: "NOTHING" }].concat(rowsCopy) };
    });
  }

  render() {
    return (
      <div>
        <table>
          <tbody>
            {this.state.rows.map((t, i) => this.renderTableRow(t, i))}
          </tbody>
        </table>
        <button onClick={this.addNewRow}>Add new first row</button>
      </div>
    );
  }
}

class Row extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      //it's not working either
      //text: props.text
    };
  }

  render() {
    //if its "value" (instead of defaultValue), text area cannot be edited. When the onChange event is implemented, the same issue appears again
    return (
      <tr>
        <td>
          <textarea defaultValue={this.props.text} />
        </td>
      </tr>
    );
  }
}

// ========================================

ReactDOM.render(<List />, document.getElementById("root"));

我想动态地将行添加到应该可编辑的表的开头。在我看来,这个解决方案应该可以工作,但表格以错误的方式显示行值(最后一行文本重复,没有显示“NOTHING”文本)。使用“价值道具”+“onChange 事件”方法没有帮助。你能帮我解决这个问题吗? 谢谢!

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    这是因为您使用数组索引作为键。一开始你的 first 行的 key 为 0,second 的 key 为 1。当你添加 NOTHING 时,它得到的 key 为 0,first 得到 1,second 得到 2。由于您使用的是 defaultValue,因此行中的值(键为 0)不会更新使用更新的文本道具,因为它已经将“第一个”文本作为默认值。如果您分配一个随机值(一些唯一值)作为键而不是索引return &lt;Row key={Math.random()} {...t} /&gt;;,它会起作用(我不推荐 Math.random,我只是在证明它有效)。

    ALSO(不改变 List 组件)

    我们可以让它与 valueonChange 一起工作。如果组件接收到不同的文本值,我们只需要在 Row 中更新 val 的状态。 像这样(在 Row 内)

    constructor(props) {
        super(props);
        this.state = { val: props.text };
    }
    
    componentWillReceiveProps(nextProps){
        if(nextProps.text !== this.props.text){
             this.setState({ val: nextProps.text })
        }
    }
    
    render(){
        ....
        <textarea value={this.state.val} onChange={({target}) => this.setState({ val: target.value })} />
    

    【讨论】:

    • 感谢您的解释和第二个解决方案!
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 2017-01-16
    • 2019-07-08
    • 1970-01-01
    相关资源
    最近更新 更多