0

I'm new with React and TypeScript. I want to add a new row in a table when someone clicks a button (FontAwesomeIcon). I actually don't even know where to start.

Here's my code

import React from "react";
import './SchemeFillData.scss';
import {faPlus} from "@fortawesome/free-solid-svg-icons/faPlus";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";

export function SchemeFillData() {
    return <div className='schemedata'>
            <table className='schemedata__attr'>
                <thead>
                <th className='schemedata__attr__title' colSpan={2}>
                    Atrybuty
                    <FontAwesomeIcon className='schemedata__add' icon={faPlus} size='lg' color='lightgray'/>
                </th>
                </thead>
                <tbody>
                <tr>
                    <td className='scheme__attr__cell'>
                        <input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text'
                               id='unit'/>
                    </td>
                    <td className='scheme__attr__cell'>
                        <select id="defVat" className='schemedata__select attr__select'>
                            <option value="" disabled selected>Wybierz kolumnę</option>
                        </select>
                    </td>
                </tr>
                </tbody>
            </table>
    </div>;
}

What do I need to do? Where to start? Thanks for the answers :)

0

3 Answers 3

1
  1. You need to have a state property initialized with an empty array
  2. You need to bind a function to the button, which adds an object to this array
  3. In the JSX, you need to map on this array, and for every element in it, you add a tr tag with a td and a message in it

You can try something like this maybe :

import React, { useState } from "react";
import './SchemeFillData.scss';
import {faPlus} from "@fortawesome/free-solid-svg-icons/faPlus";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";

export function SchemeFillData() {
    const [array, setArray] = useState([]);

    function addNewRow() {
      setArray([...array, {}]);
    }

    return <div className='schemedata'>
            <table className='schemedata__attr'>
                <thead>
                <th className='schemedata__attr__title' colSpan={2}>
                    Atrybuty
                    <FontAwesomeIcon className='schemedata__add' icon={faPlus} size='lg' color='lightgray' onClick={addNewRow} />
                </th>
                </thead>
                <tbody>
                <tr>
                    <td className='scheme__attr__cell'>
                        <input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text'
                               id='unit'/>
                    </td>
                    <td className='scheme__attr__cell'>
                        <select id="defVat" className='schemedata__select attr__select'>
                            <option value="" disabled selected>Wybierz kolumnę</option>
                        </select>
                    </td>
                </tr>
                {array && array.map((_, index) => (
                  <tr key={index}> <td className='scheme__attr__cell'> <input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text' id='unit'/> </td> <td className='scheme__attr__cell'> <select id="defVat" className='schemedata__select attr__select'> <option value="" disabled selected>Wybierz kolumnę</option> </select> </td> </tr>
                )}
                </tbody>
            </table>
    </div>;
}

Sign up to request clarification or add additional context in comments.

6 Comments

I have to put exactly the same row as I have above
What should I put in here? setArray([...array, newElement]); Where you put ...array to be exact
copy paste the file like this, and tell me if you get an error :)
Here is one: imgur.com/a/Ec2IcZH And here's another one: imgur.com/a/HAzggWC
oh yes you're using TypeScript so there are error types, I edited a bit
|
0

using typescript, you can do it like this :

I made a codesandbox demo if you want to check


    import React, { useState }from "react";
    import "./styles.css";
    
    // this type describe how the data of each rows should be shaped
    type RowData = {
      message: string;
    }

    // here we define an inteface to describe the shape of our component state
    // this is an object with a key 'rows' who contains an array of RowData
    interface IState {
      rows: RowData[];
    }
    
    export default function App() {
      // here we are controlling the parameters of useState function with our IState interface
      const [state, setState] = useState<IState>({rows: []});
    
      const addRow = () => {
        setState({
          rows: [...state.rows, { message: "my new element" }]
        })
      } 
    
      const { rows } = state;
    
      return (
        <div className='schemedata'>
          <table className='schemedata__attr'>
              <thead>
                <th className='schemedata__attr__title' colSpan={2}>
                    Atrybuty
                    <button onClick={addRow}>Add row</button>
                </th>
              </thead>
              <tbody>
                { rows.map(element => (
                    <tr> 
                      <td className='scheme__attr__cell'> 
                        <input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text' id='unit'/> 
                      </td> 
                      <td className='scheme__attr__cell'> 
                        <select id="defVat" className='schemedata__select attr__select'> 
                            <option value="" disabled selected>{element.message}</option> 
                        </select> 
                      </td> 
                    </tr>
                  ))
                }
              </tbody>
          </table>
        </div>
      );
    }

    enter code here

Comments

0

Ok, you should read the react documentation to know how this frameworks work, but essentially, you need to render your "table-rows" from a state variable. So to make it simple to understand, lets say you have a variable rows=[]. You need to make a function that adds something to that row :

  const addRow = (someText) => {
    this.rows.push({content: someText}
  }

And you should call that function whenever someone clicks on your button. That will add a new object in your array. And if you have your rows mapped to that variable it should work as a basic version:

<tbody>
  {this.state.rows.map(( obj, index ) => {
      return (
        <tr key={index}>
          <td>{obj.content}</td>
        </tr>
      );
    })}
</tbody>

Comments

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.