在ReactJS中动态添加行到现有表

时间:2019-01-31 06:42:57

标签: reactjs

我正在学习ReactJS。

我有一个已存在的表,该表包含thead,默认情况下只有1行。现在单击按钮时,我想每次单击按钮时都添加一行,但是添加的最大行数不应大于4。

这是我的代码:

import React, { Component } from "react";
import Sidebar from "../Home/Sidebar";
import axios from "axios";
import $ from "jquery";
import { isDivisibleBy100 } from "../utils/utility";
import { Chart } from "react-charts";

class Strategy extends Component {
  state = {
    Price: [],
    chart_data: [],
    loadData: true,
    unit: parseFloat(0),
    loadUnit: true,

  };

  componentDidMount() {
    this.getPriceList();
  }

  getPriceList() {
    axios.get("http://localhost:8000/listprice/").then(res => {
      if (res.data.result === 1) {
        this.setState({ Price: res.data.data });
      }
    });
  }


  appendRow(event) {
    var rel = event.target.getAttribute("rel");
    rel = parseInt(rel) + 1;
    console.log(rel);
    var addRow = (
      <tr>
        <td>
          <input type="text" id={`select-type` + rel} />
        </td>
        <td>
          <input type="text" id={`select-position` + rel} />
        </td>
      </tr>
    );
    $(".table tbody").append(appRow);
  }

  render() {
    return (
      <div className="container container_padding">
        <div className="row">
          <Sidebar />
          <div className="col-md-9 col-sm-9 col-xs-12 white-box">
            <div className="col-sm-12">
              <h3 className="col-sm-4" style={{ padding: "0px" }}>
                Strategy Plan:
              </h3>
              <div className="col-sm-7" />
              <div className="col-sm-1" style={{ marginTop: "15px" }}>
                <button
                  rel="1"
                  type="button"
                  id="addbtn"
                  className="btn btn-circle"
                  onClick={this.appendRow}
                >
                  <i className="fa fa-plus" />
                </button>
              </div>
            </div>
            <div className="col-sm-12 a">
              <div className="table-responsive">
                <table className="table table-bordered">
                  <thead>
                    <tr>
                      <td>#</td>
                      <td>Type</td>
                      <td>Position</td>
                      <td>Price</td>
                      <td>Number</td>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                      <td>1</td>
                      <td>
                        <select
                          className="form-control"
                          name="select-type"
                          id="select-type"
                        >
                          <option value="select">Select</option>
                          <option value="one">1</option>
                          <option value="two">2</option>
                        </select>
                      </td>
                      <td>
                        <select
                          className="form-control"
                          name="select-position"
                          id="select-position"
                        >
                          <option value="select">Select</option>
                          <option value="a">A</option>
                          <option value="b">B</option>
                        </select>
                      </td>
                      <td>
                        <select
                          className="form-control"
                          name="price-list"
                          id="price-list"
                          onChange={event =>
                            this.handlePriceChange(event)
                          }
                        >
                          <option value="select">Select</option>
                          {this.state.Price.map(p => (
                            <option
                              value={p.pprice}
                              key={p.price}
                            >
                              {p.price}
                            </option>
                          ))}
                        </select>
                      </td>
                      <td style={{ width: "180px" }}>
                        <input
                          id="input-number"
                          type="text"
                          className="form-control"
                          defaultValue="1"
                        />
                      </td>
                    </tr>


                  </tbody>
                </table>
              </div>
            </div>
            <div className="col-sm-12">
              <button
                className="btn"
                onClick={() => this.handleClick()}
              >
                Calculate
              </button>
            </div>

            {this.state.loadData ? (
              ""
            ) : (
              <div
                style={{
                  width: "600px",
                  height: "300px",
                  marginTop: "35px",
                  marginLeft: "25px",
                  marginBottom: "10px"
                }}
              >
                <Chart
                  data={this.state.chart_data}
                  series={{ type: "line" }}
                  axes={[
                    { primary: true, type: "linear", position: "bottom" },
                    { type: "linear", position: "left" }
                  ]}
                  primaryCursor
                  secondaryCursor
                  tooltip
                />
              </div>
            )}
          </div>
        </div>
      </div>
    );
  }
}

export default Strategy;

appendRow函数未附加该行。

我想念什么?有没有更好的方法可以实现这一目标?

请提出建议。

预先感谢

2 个答案:

答案 0 :(得分:1)

您正在使用jquery并直接处理真实DOM。在React中,我们使用虚拟DOM,而不处理真实​​的DOM。与Jquery不同,在React中,您不必担心处理UI。您的关注点应该是正确处理数据,将UI更新留给React。您尚未在此处提供表组件信息。因此,我将为您提供一个代码示例,该代码示例完全可以实现您想要实现的目标。对于按钮,您可以将其放置在此组件中所需的位置。

import React from "react";

class Table extends React.Component {
  state = {
    data: []
  };
  appendChild = () => {
    let { data } = this.state;
    data.push(data.length); // data.length is one more than actual length since array starts from 0.
    // Every time you call append row it adds new element to this array. 
    // You can also add objects here and use that to create row if you want.
    this.setState({data});
  };
  render() {
    return (
      <table>
        <thead>
          <th>Type</th>
          <th>Position</th>
        </thead>
        <tbody>
          {this.state.data.map(id => (
            <Row id = {id} />
          ))}
        </tbody>
      </table>
    );
  }
}

const Row = ({ id }) => (
  <tr>
    <td>
      <input type="text" id={`select-type-${id}`} />
    </td>
    <td>
      <input type="text" id={`select-position-${id}`} />
    </td>
  </tr>
);

答案 1 :(得分:0)

构造方法:

constructor(props) {
  super(props)
  this.state = {rows: []};
}

在您的appendRow方法内部,没有将tr直接添加到tbody,而是将tr添加到rows state

appendRow(event) {
  var rel = event.target.getAttribute("rel");
  rel = parseInt(rel) + 1;

  var joined = this.state.rows.concat(
  <tr>
    <td>
      <input type="text" id={`select-type` + rel} />
    </td>
    <td>
      <input type="text" id={`select-position` + rel} />
    </td>
  </tr>
  );
  this.setState({ rows: joined })
}

在您的render方法内,只需将数组放入。只要调用setState,它将重新呈现:

render() {
  ...
  return (
     ...
     <button
       rel="1"
       type="button"
       id="addbtn"
       className="btn btn-circle"
       onClick={this.appendRow}>
       <i className="fa fa-plus" />
     </button>
     ...
     <tbody>
       {this.state.rows}
     </tbody>
     ...
  )
  ...
}