0

I have a react component, wherein I render table rows dynamically. I want to trigger onClick event of a button with its id.

Here is my code:

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

class Strategy extends Component {
  state = {
    Price: [],
    loadPrice: true,
    loadData: true,
    data: [],
    errorMsg: ""
  };

  componentDidMount() {
    this.getPriceList();
    let { data } = this.state;
    data.push(data.length);
    this.setState({ data });
  }

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

  ...

  appendChild = () => {
    let { data } = this.state;
    if (data.length < 4) {
      data.push(data.length);
      this.setState({ data });
    } else {
      this.setState({ errorMsg: "You cannot add more than 4 rows." });
      setTimeout(() => {
        this.setState({ errorMsg: "" });
      }, 3000);
    }
  };

  render() {
    return (
      <div className="container container_padding">
        <div className="row">
          <div className="col-md-9 col-sm-9 col-xs-12 white-box">
            ...
            <div className="col-sm-12" style={{ marginBottom: "50px" }}>
              <table className="table table-bordered">
                <thead>
                  <tr>
                    <td>#</td>
                    <td>Type</td>
                    <td>Position</td>
                    <td>Price</td>
                    <td>No.</td>
                    <td></td>
                  </tr>
                </thead>
                <tbody>
                  {this.state.loadPrice
                    ? ""
                    : this.state.data.map((id, i) => (
                        <Row
                          key={i}
                          id={id}
                          strikeprice={this.state.Price}
                        />
                      ))}
                </tbody>
              </table>

            </div>
            <div className="col-sm-12">
              ...
            </div>
          </div>
        </div>
      </div>
    );
  }
}

const Row = ({ id, price }) => (
  <tr>
    <td>{id + 1}</td>
    <td>
      <select
        className="form-control"
        name={`select-type-${id}`}
        id={`select-type-${id}`}
      >
        <option value="select">Select</option>
        <option value="a">A</option>
        <option value="b">B</option>
      </select>
    </td>
    <td>
      <select
        className="form-control"
        name={`select-position-${id}`}
        id={`select-position-${id}`}
      >
        <option value="select">Select</option>
        <option value="long">Long</option>
        <option value="short">Short</option>
      </select>
    </td>
    <td>
      <select
        className="form-control"
        name={`price-list-${id}`}
        id={`price-list-${id}`}
      >
        <option value="select">Select</option>
        {price.map(p => (
          <option value={p.price} key={p.price}>
            {p.price}
          </option>
        ))}
      </select>
    </td>
    <td style={{ width: "180px" }}>
      <input
        id={`input-lot-size-${id}`}
        type="text"
        className="form-control"
        defaultValue="1"
      />
    </td>
    <td>
      <button onClick={'onclick event here'} rel={id} className="btn btn-circle-remove" id={`btn-remove-${id}`}><i className="fa fa-minus"></i></button>
    </td>
  </tr>
);

export default Strategy;

In the const Row I need a button, which when clicked the current row will be removed. But here, we cannot call any function like: this.removerow here in const Row. What is a possible way I could call a function here dynamically, and remove that current row in ReactJS.

How can I achieve this here?

Thanks in advance.

0

1 Answer 1

1

You should create it in the parent component and pass the handler down as a prop.

So your Strategy should have something like

removeRow = (event) => {
    const id = Number(event.currentTarget.getAttribute('rel'));
    // here you must remove it from the data in the state
    const data = this.state.data.filter(value=>value !== id);
    this.setState({data});
}

and when you create the rows do

this.state.data.map((id, i) => (
                    <Row
                      key={id}
                      id={id}
                      strikeprice={this.state.Price}
                      onRemove={this.removeRow}
                    />
                  ))

and finally in your Row component

const Row = ({ id, price, onRemove }) => (

and

<button onClick={onRemove} rel={id} className="btn btn-circle-remove" id={`btn-remove-${id}`}><i className="fa fa-minus"></i></button>
Sign up to request clarification or add additional context in comments.

5 Comments

I tried this, in removeRow function when i console.log(id), it gives undefined.
Ok, in you removeRow(), I just updated the setstate like: this.setState({ data: this.state.data.slice(0, -1) });, and got me working.
@ReemaParakh this will always remove the last one and not the one you clicked.
@ReemaParakh updated the answer. Use const id = Number(event.currentTarget.getAttribute('rel')); to get the id. But you also need to use id as the key of the Row instead of i. Working example at codesandbox.io/s/p59w613wzj
@ReemaParakh see my previous comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.