Home > Software engineering >  I want to put my two states input data into a table in react
I want to put my two states input data into a table in react

Time:12-31

enter image description here

I want to put the input data into a table rows. But my data is going on different lines with different tags. I have only made one tag in my imported component.

This is the Main Component

 import './App.css';
    import { useState } from 'react'
    import Data from './Data';
    
    function Component() {
    
        const [IdData, setIdData] = useState()
        const [Input, setInput] = useState()
        const [Items, setItems] = useState([])
    
        const addData = () => {
            setItems((newData) => {
                return [...newData, IdData, Input]
            })
           
            setInput("");
            setIdData("");
        }
    
        const idChange = (e) => {
            setIdData(e.target.value)
        }
        const inputChange = (e) => {
            setInput(e.target.value)
        }
    
      return (
        <>
          <div className="main">
    
          <div className="center">
              <br />
              <h2>Table Layout</h2>
            <div className="inner">
                <input className="id" type="number" autoFocus onChange={idChange} value={IdData} placeholder='ID' />
                <input type="text" placeholder='Name' onChange={inputChange} value={Input}/>
                <i className='fa fa-check' onClick={addData}></i>
            </div>
    
    
    
    
                {
                    Items.map((todoItems, index) => {
                        return <Data data={todoItems}key={index} />
    
                     
                    })
                }
                
            
          </div>
    
          </div>
        </>
      );
    }

export default Component;

I want to put the input data into a table rows. But my data is going on different lines with different tags. I have only made one tag in my imported component. This is the imported component

import React from 'react'
// import './App.css'

function Data(props) {
    return (
        <>
        <table>

            <tr>
            <th>ID</th>
            <th>Name</th>
            </tr>
            <tr>
            <tbody>
                
                <td>{props.data}</td>
            </tbody>
            </tr>
        </table>

            
                    {/* <td><i className='fa fa-times'></i></td> */}
        </>
    )
}

export default Data

I want to put the input data into a table rows. But my data is going on different lines with different tags. I have only made one tag in my imported component.

This is the CSS File

@import url('https://fonts.googleapis.com/css2?family=The Nautigal:wght@700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Manrope&family=The Nautigal:wght@700&display=swap');

* {
  padding: 0;
  margin: 0;
}
.main {
  background-image: linear-gradient(to left, #5f2c82, #49a09d);
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
p {
  display: inline;
}

.center  h2 {
  font-family: 'The Nautigal', cursive;
  font-size: 50px;
  text-align: center;
}
.center {
  /* display: flex; */
  align-items: center;
  justify-content: center;
  background: white;
  width: 40%;
  height: 80%;
  border-radius: 20px;
}
.inner {
  width: 100%;
  margin: 30px 0 0 40px;  
  display: flex;
  flex-direction: row;
  justify-content: left;
}

.data {
  /* width: 20%; */
  font-family: 'Manrope', sans-serif;
  display: flex; 
  /* flex-direction: row; */
  /* justify-self: stretch; */
  margin: 10px 39px 0 39px;
  font-size: 16px;
  background: rgb(216, 216, 216);
  /* border-radius: 10px; */
  padding: 10px 10px;
  position: relative;
  /* width: 100%;  */
}
.inline {
  display: flex;
  flex-direction: row-reverse;
}
.data:after {
  content: '';
  position: absolute;
  height: 42px;
  top: 0px;
  left: 0px;
  background: linear-gradient(to left, #5f2c82, #49a09d);
  width: 5px;
}

.data:hover {
  background: linear-gradient(to left, #5f2c82, #49a09d);
  color: white;
  cursor: pointer;
}
.inner input {
  display: flex;
  justify-content: center;
  width: 60%;
  padding: 10px 5px;
  font-size: 18px;
  border-radius: 8px;
  outline: none;
  border: 1px solid grey;
}
.inner .id {
  width: 10%;
  margin-right: 5px;
}
.fa-check {
  background: linear-gradient(to left, #5f2c82, #49a09d);
  opacity: 0.7;
  
  border-radius: 8px;
  color: white;
  font-size: 24px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 9%;
  margin-left: 5px;
}

.fa-check:hover {
  cursor: pointer;
  opacity: 1;
}

CodePudding user response:

Just try changing setITems as:

setItems((newData) => {
    return [...newData].concat([[IdData, Input]]);
});

CodePudding user response:

Here's how I would approach it. Have two states: one to maintain the dataset (an array of objects), the other to maintain the current state of the form (an object).

When the inputs change a handler is called to update the form state, and when the button is clicked the current state of the form is added to the dataset array.

<Table> accepts the data state so when that changes the table changes.

const { useState } = React;

function Example() {

  // Initialise the states
  const [ data, setData, ] = useState([]);
  const [ form, setForm ] = useState({ id: '', name: '' });

  // I've attached one listener to the form element
  // (event delegation) which means that I need to check
  // that the event has come from the right element first,
  // and then I can update the form with
  // the name/value of the input
  function handleChange(e) {
    const { nodeName, name, value } = e.target;
    if (nodeName === 'INPUT') {
      setForm({...form, [name]: value })
    }
  }

  // Add the current form state to the dataset,
  // and reset the form
  function addEntry() {
    setData([ ...data, form ]);
    setForm({ id: '', name: '' });
  }

  // Only enable the button if both
  // fields are completed
  function isButtonDisabled() {
    return !form.id || !form.name;
  }

  return (
    <div>
      <form onChange={handleChange}>
        <fieldset>
          <legend>ID</legend>
          <input name="id" type="text" value={form.id} />
        </fieldset>
        <fieldset>
          <legend>Name</legend>
          <input name="name" type="text" value={form.name} />
        </fieldset>
        <button
          type="button"
          onClick={addEntry}
          disabled={isButtonDisabled()}
        >Add entry
        </button>
      </form>
      <Table data={data} />
    </div>
  );
};

function Table({ data }) {
  
  // Separate function to build the rows
  // from the array of objects
  function buildRows(data) {
    return data.map(obj => {
      return (
        <tr key={obj.id}>
          <td>{obj.id}</td>
          <td>{obj.name}</td>
        </tr>
      );
    });
  }
  
  // Don't show anything if the dataset is empty
  if (!data.length) return <div />;
  
  return (
    <table>
      <tbody>
        <tr className="heading">
          <td>ID</td>
          <td>Name</td>
        </tr>
        {buildRows(data)}
      </tbody>
    </table>
  );
}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
button { margin-top: 1em; margin-left: auto; margin-right: auto; width: 50%; display: block; }
table { border-collapse: collapse; border: 1px solid black; margin-top: 1em; width: 75%; margin-left: auto; margin-right: auto; }
td { padding: 0.3em; border: 1px solid #565656; }
.heading { font-weight: 700; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

  • Related