简体   繁体   English

react的输入值与dom不同步

[英]input value of react doesn't not sync with dom

I have a loop to render bunch of input, it's dynamic, user can add row and delete row, but the value entered is not sync when a element is destroyed. 我有一个循环来渲染一堆输入,它是动态的,用户可以添加行和删除行,但是当元素被破坏时输入的值不同步。

as you can see in the demo, I deleted '2' but '3' got deleted and 2 is still there. 正如您在演示中看到的那样,我删除了“ 2”,但删除了“ 3”,而2仍然存在。

在此处输入图片说明

Code: https://codesandbox.io/s/4x0x17zykx 代码: https//codesandbox.io/s/4x0x17zykx

It is because of your deleteRow method. 这是因为您的deleteRow方法。

deleteRow = () => this.setState({ rowCount: this.state.rowCount - 1 });

This method just changes state.rowCount value, and when the render method is called, you're rendering rows from 0 to rowCount. 此方法仅更改state.rowCount值,并且在调用render方法时,您正在将行从0渲染到rowCount。

return <div>{times(rowCount, this.renderRow)}</div>;

Thus, you are effectively removing the last row, and not the row you clicked on. 因此,您实际上是在删除最后一行,而不是删除单击的行。

EDIT : You can have the expected behavior with some changes (Creating an array of rows within the state, updating deleteRow and addRow methods to work properly and add an onChange event on the inputs to show that the removed row is the expected one) 编辑:您可以通过某些更改获得预期的行为(在状态内创建一个行数组,更新deleteRow和addRow方法以使其正常工作,并在输入上添加onChange事件以显示所删除的行是预期的行)

import React from "react";
import ReactDOM from "react-dom";
import times from "lodash.times";

export class MultipleInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rows: [{type: "", value: ""}],
    };
  }


  addRow = () => {
    this.setState((prevState) => ({
      rows: prevState.rows.concat({type: "", value: ""})
    }));
  };

  deleteRow = (i) => {
    this.setState((prevState) => ({
      rows: prevState.rows.filter((_, index) => index !== i)
    }));
  };

  onChange = (e, i) => {
    let rows = this.state.rows.slice();
    rows[i].value = e.target.value;
    this.setState(
      rows: rows,
    );
  };

  renderRow = (i) => {
    return (
      <div>
        <input index={i} type={this.state.rows[i].type} value={this.state.rows[i].value} onChange={(e) => this.onChange(e, i)}/>
        {i === 0 && <button onClick={() => this.addRow()}>add row</button>}
        {i > 0 && <button onClick={() => this.deleteRow(i)}>x</button>}
      </div>
    );
  };

  render() {
    return <div>{times(this.state.rows.length, this.renderRow)}</div>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<MultipleInput />, rootElement);

This code is certainly not the cleanest or more efficient one, but it is working and (I hope) is free of react anti-pattern. 这段代码当然不是最干净或更有效的代码,但是它正在工作,并且(我希望)没有任何反作用模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM