来自JSON的反应表删除行不刷新

我有表,从JSON呈现。

{
  key: 1,
  model: "11111111",
  sn: "TERR5RRTR555465",
  fv: "FV/12344/2019"
},
{
  key: 2,
  model: "2222222",
  sn: "TERR5RRTR555465",
  fv: "FV/12344/2019"
},
{
  key: 3,
  model: "33333", 
  sn: "TERR5RRTR555465",
  fv: "FV/12344/2019"
},
{
  key: 4,
  model: "44444444",
  sn: "TERR5RRTR555465",
  fv: "FV/12344/2019"
}

行具有从表中删除行的按钮。双击后,从JSON中删除了行,但在页面上仅删除了表中的最后一行。而且,如果我删除了另一条随机行,则页面上将始终删除最后一行。

问题出在哪里,我在REACT中不了解什么?

我的REACT示例:

https://codesandbox.io/embed/react-table-array-99xiq

和代码:

import React from "react";

import { Button, Form, Input, Message, Table } from "semantic-ui-react";
import "./styles.css";
import "semantic-ui-css/semantic.min.css";

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      lista: [
        {
          key: 1,
          model: "11111111",
          sn: "TERR5RRTR555465",
          fv: "FV/12344/2019"
        },
        {
          key: 2,
          model: "2222222",
          sn: "TERR5RRTR555465",
          fv: "FV/12344/2019"
        },
        { key: 3, model: "33333", sn: "TERR5RRTR555465", fv: "FV/12344/2019" },
        {
          key: 4,
          model: "44444444",
          sn: "TERR5RRTR555465",
          fv: "FV/12344/2019"
        },
        { key: 5, model: "5555555", sn: "TERR5RRTR555465", fv: "FV/12344/2019" }
      ]
    };
    this.toDoChangeValues = this.toDoChangeValues.bind(this);
    this.removeListIndex = this.removeListIndex.bind(this);
  }

  toDoChangeValues(n, v) {
    var nam = n.split("_");
    var list = this.state.lista;
    var indx = list.findIndex(x => x.key == nam[1]);
    list[indx][nam[0]] = v;
    this.setState({ lista: list });
  }

  removeListIndex(n) {
    this.setState(prevState => ({
      lista: prevState.lista.filter(row => row.key != n)
    }));
  }

  render() {
    if (
      this.state.lista.find(function(x) {
        return x.model === "" && x.sn === "" && x.fv === "";
      }) === undefined
    ) {
      var new_id = Math.max.apply(null, [
        ...this.state.lista.map(function(o) {
          return o.key;
        }),
        0
      ]);
      this.setState({
        lista: [
          ...this.state.lista,
          { key: new_id + 1, model: "", sn: "", fv: "" }
        ]
      });
    }
    const { lista } = this.state;
    return (
      <>
        <div className="segm_space">
          <Message attached header="Table list" />
          <Form className="attached fluid segment">
            <Table
              basic="very"
              celled
              compact
              className="list_hardwares"
              unstackable
            >
              <Table.Header>
                <Table.Row>
                  <Table.HeaderCell>Data</Table.HeaderCell>
                  <Table.HeaderCell>Number</Table.HeaderCell>
                  <Table.HeaderCell>Type</Table.HeaderCell>
                  <Table.HeaderCell style={{ width: "1%" }} />
                </Table.Row>
              </Table.Header>

              <Table.Body>
                {lista.map(
                  function(object) {
                    return (
                      <RowData
                        obj={object}
                        rmveIndx={this.removeListIndex}
                        chVal={this.toDoChangeValues}
                      />
                    );
                  }.bind(this)
                )}
              </Table.Body>
            </Table>
          </Form>
        </div>
      </>
    );
  }
}

export class RowData extends React.Component {
  constructor() {
    super();
    this.state = {
      trash: false
    };
    this.onTodoChange = this.onTodoChange.bind(this);
    this.onTrash = this.onTrash.bind(this);
  }

  onTodoChange(e) {
    const { name, value } = e.target;
    this.props.chVal(name, value);
  }

  onTrash(e) {
    if (!this.state.trash) {
      this.setState({ trash: true }, () => {
        setTimeout(
          function() {
            this.setState({ trash: false });
          }.bind(this),
          2000
        );
      });
    } else {
      this.props.rmveIndx(e.target.name || e.target.closest("button").name);
    }
  }

  render() {
    return (
      <Table.Row id={"id_" + this.props.obj.key}>
        <Table.Cell>
          <Input
            fluid
            transparent
            onChange={this.onTodoChange}
            name={"model_" + this.props.obj.key}
            placeholder="00000000000"
            defaultValue={this.props.obj.model}
          />
        </Table.Cell>
        <Table.Cell>
          <Input
            fluid
            transparent
            onChange={this.onTodoChange}
            name={"sn_" + this.props.obj.key}
            placeholder="XXXXXXXXXXXXXXX"
            defaultValue={this.props.obj.sn}
          />
        </Table.Cell>
        <Table.Cell>
          <Input
            fluid
            transparent
            onChange={this.onTodoChange}
            defaultValue={this.props.obj.fv}
          />
        </Table.Cell>
        <Table.Cell>
          <Button
            name={this.props.obj.key}
            onClick={this.onTrash}
            color={this.state.trash ? "blue" : undefined}
            compact
            size="tiny"
            icon="trash"
          />
        </Table.Cell>
      </Table.Row>
    );
  }
}
评论
  • 景长星
    景长星 回复

    代码中几乎没有错误: 1.您不需要在render函数中设置setState。

    //Your Code
    this.setState({
            lista: [
              ...this.state.lista,
              { key: new_id + 1, model: "", sn: "", fv: "" }
            ]
          });
    
    
    1. 您不需要在onClick上传递侦听器,即
    this.props.rmveIndx(e.target.name || e.target.closest("button").name);
    

    到(您不需要它。您只需执行此操作)

    onTrash(e) {
        this.props.rmveIndx();
      }
    
    
    1. 而不是传递e.target.name || e.target.closest(“ button”)。name只是传递对象(如果将来需要其他数据,它将更容易),即
    
        {lista.map(object => <RowData
                          obj={object}
                          rmveIndx={() => this.removeListIndex(object)} //Note here
                          chVal={this.toDoChangeValues}
                        />)
    
    
    1. 根据键过滤数据:
    removeListIndex(n) {
        this.setState(prevState => ({
          lista: prevState.lista.filter(row => row.key !== n.key)
        }));
      }
    
    
    1. 最重要的是,自从其输入控件开始以来,您已将所有输入值都设置为defaultValue,因此您需要在value属性中传递值。再次阅读文档,以使您在语义上更加清晰。我可以解释,但要学会;-)
    <Table.Row id={"id_" + this.props.obj.key}>
            <Table.Cell>
              <Input
                fluid
                transparent
                onChange={this.onTodoChange}
                name={"model_" + this.props.obj.key}
                placeholder="00000000000"
                defaultValue={this.props.obj.model}
                value={this.props.obj.model}
              />
            </Table.Cell>
            <Table.Cell>
              <Input
                fluid
                transparent
                onChange={this.onTodoChange}
                name={"sn_" + this.props.obj.key}
                placeholder="XXXXXXXXXXXXXXX"
                defaultValue={this.props.obj.sn}
                value={this.props.obj.sn}
              />
            </Table.Cell>
            <Table.Cell>
              <Input
                fluid
                transparent
                onChange={this.onTodoChange}
                defaultValue={this.props.obj.fv}
                value={this.props.obj.fv}
              />
            </Table.Cell>
            <Table.Cell>
              <Button
                name={this.props.obj.key}
                onClick={this.onTrash}
                color={this.state.trash ? "blue" : undefined}
                compact
                size="tiny"
                icon="trash"
              />
            </Table.Cell>
          </Table.Row>
    

    Here is working code sandbox link : https://codesandbox.io/s/react-table-array-rinfw

    注意:我评论了您的一些代码。它只是指导其工作原理的逻辑。您可以从此处注释并携带您的代码