来自json的反应表删除行未刷新

问题描述 投票:0回答:2

我有表格,从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>
    );
  }
}
arrays reactjs html-table removechild
2个回答
0
投票

代码中有几个错误:1.您无需在渲染函数中进行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
,因为它是受控组件,因此您需要在值属性中传递值。再次阅读文档,以使您在语义上更加清晰。我可以解释,但要学会;;)
<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>

这里是工作代码沙箱链接:https://codesandbox.io/s/react-table-array-rinfw

Note

:我评论了您的一些代码。它只是指导其工作原理的逻辑。您可以从此处评论并携带您的代码
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 = {
      inputFocus: null,
      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" }
      ]
    };
  }

  handleChange = (value,name,id) => {
    const {lista} = this.state;
    const newData = [...lista.filter(item => item.key !== id), { ...lista.filter(item => item.key === id)[0], [name]: value}];
    this.setState({lista: newData});
  }

  addData = () => {
    const {lista} = this.state;
    this.setState({ lista: [...lista, { key: lista[lista.length - 1].key + 1, model: this.model.inputRef.current.value, sn: this.sn.inputRef.current.value, fv: this.fv.inputRef.current.value}]});
    this.model.inputRef.current.value = '';
    this.sn.inputRef.current.value = '';
    this.fv.inputRef.current.value = '';
  }

  trash = (id) => {
    this.setState({lista: this.state.lista.filter(item => item.key !== id)});
  }

  render() {
    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.sort((prev,next) => {
                  if (prev.key > next.key) return 1;
                  return -1;
                }).map(item => <Table.Row key={item.key}>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='model'
                      onChange={(e,data) => this.handleChange(data.value,data.name, item.key)}
                      placeholder="00000000000"
                      defaultValue={item.model}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='sn'
                      onChange={(e, data) => this.handleChange(data.value, data.name, item.key)}
                      placeholder="XXXXXXXXXXXXXXX"
                      defaultValue={item.sn}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='fv'
                      onChange={(e, data) => this.handleChange(data.value, data.name, item.key)}
                      defaultValue={item.fv}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Button
                      onClick={() => this.trash(item.key)}
                      compact
                      size="tiny"
                      icon="trash"
                    />
                  </Table.Cell>
                </Table.Row>)}
                <Table.Row>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='model'
                      ref={n => this.model = n}
                      placeholder="00000000000"
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='sn'
                      ref={n => this.sn = n}
                      placeholder="XXXXXXXXXXXXXXX"
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='fv'
                      ref={n => this.fv = n}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Button
                      compact
                      size="tiny"
                      icon="add"
                      onClick={this.addData}
                    />
                  </Table.Cell>
                </Table.Row>
              </Table.Body>
            </Table>
          </Form>
        </div>
      </>
    );
  }
}

Edit react-table-array


0
投票
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 = {
      inputFocus: null,
      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" }
      ]
    };
  }

  handleChange = (value,name,id) => {
    const {lista} = this.state;
    const newData = [...lista.filter(item => item.key !== id), { ...lista.filter(item => item.key === id)[0], [name]: value}];
    this.setState({lista: newData});
  }

  addData = () => {
    const {lista} = this.state;
    this.setState({ lista: [...lista, { key: lista[lista.length - 1].key + 1, model: this.model.inputRef.current.value, sn: this.sn.inputRef.current.value, fv: this.fv.inputRef.current.value}]});
    this.model.inputRef.current.value = '';
    this.sn.inputRef.current.value = '';
    this.fv.inputRef.current.value = '';
  }

  trash = (id) => {
    this.setState({lista: this.state.lista.filter(item => item.key !== id)});
  }

  render() {
    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.sort((prev,next) => {
                  if (prev.key > next.key) return 1;
                  return -1;
                }).map(item => <Table.Row key={item.key}>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='model'
                      onChange={(e,data) => this.handleChange(data.value,data.name, item.key)}
                      placeholder="00000000000"
                      defaultValue={item.model}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='sn'
                      onChange={(e, data) => this.handleChange(data.value, data.name, item.key)}
                      placeholder="XXXXXXXXXXXXXXX"
                      defaultValue={item.sn}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='fv'
                      onChange={(e, data) => this.handleChange(data.value, data.name, item.key)}
                      defaultValue={item.fv}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Button
                      onClick={() => this.trash(item.key)}
                      compact
                      size="tiny"
                      icon="trash"
                    />
                  </Table.Cell>
                </Table.Row>)}
                <Table.Row>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='model'
                      ref={n => this.model = n}
                      placeholder="00000000000"
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='sn'
                      ref={n => this.sn = n}
                      placeholder="XXXXXXXXXXXXXXX"
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Input
                      fluid
                      transparent
                      name='fv'
                      ref={n => this.fv = n}
                    />
                  </Table.Cell>
                  <Table.Cell>
                    <Button
                      compact
                      size="tiny"
                      icon="add"
                      onClick={this.addData}
                    />
                  </Table.Cell>
                </Table.Row>
              </Table.Body>
            </Table>
          </Form>
        </div>
      </>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.