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>