using props to get value from a table - javascript

I am trying to build one table using props, and pass the value from that table to another function. But for some reason, the result is not displaying. What have I done wrong?
import Table from "https://cdn.skypack.dev/react-bootstrap#2.5.0";
function Tables(props) {
return (
<Table>
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
</tr>
</thead>
<tbody>
<tr>
<td>{props.first}</td>
<td>{props.second}</td>
<td>{props.third}</td>
</tr>
</tbody>
</Table>
)
}
function App() {
return (
<div>
<Tables first="Sara" />
<Tables second="Cahal" />
<Tables third="Edite" />
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

You are rendering the table three times, each one with only one prop, you need to
If you want to show one table with the three props, it should be like that.
import Table from "https://cdn.skypack.dev/react-bootstrap#2.5.0";
function Tables(props) {
return (
<Table>
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
</tr>
</thead>
<tbody>
<tr>
<td>{props.first}</td>
<td>{props.second}</td>
<td>{props.third}</td>
</tr>
</tbody>
</Table>
)
}
function App() {
return (
<div>
<Tables first="Sara" second="Cahal" third="Edite" />
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

Related

Suggestion to refactor code into simple way -React

I have multiple with the same class name and method with different parameter
i want to refactor the below code to a simpler way any suggestion would be helpful.
<table class="greyGridTable">
<tbody>
<tr>
<td>AA</td>
<td className = 'table-container'>{formatDate(someMethod1(param1,a)}</td>
</tr>
<tr>
<td>BB</td>
<td className = 'table-container'>{formatDate(someMethod1(param1,b)}</td>
</tr>
<tr>
<td>CC</td>
<td className = 'table-container'>{formatDate(someMethod1(param1,c)}</td>
</tr>
</tbody>
</table>
I want to refactor the code with the same component.
I hope this would be helpful. thanks
export const TableItems = ({data}) => {
return (
<>
{data.map(item => (
<tr>
<td>{item.name}</td>
<td className='table-container'> {item?.symbol} {formatDate(someMethod1(param1,a)}</td>
</tr>
))}
</>
)
}
const data = [
{
name: AA,
},
{
name: BB,
},
{
name: CC,
symbol: '£'
}
]
<table class="greyGridTable">
<tbody>
<TableItems data={data} />
</tbody>
</table>
Try to use an array instead. Having reusable components in an array is easy to maintain, expand and read. Definitely a good practice.
let tableItems = [{name:"AA",date:new Date()},.....]
return (
<table class="greyGridTable">
<tbody>
{tableItems.map((item,index)=>{
return(
<tr>
<td>{item.date}</td>
<td className = 'table-container'>{item.date}</td>
</tr>
)
})}
</tbody>
</table>
)

Nothing printed to the screen in the table tbody

import React from 'react';
export default class HelloWorld extends React.Component {
public render(): JSX.Element {
let elements = [{"id":1,"isActive":true,"object":"Communication","preview":"Un appercu de la communication","sentAt":{"date":"2020-12-17 15:18:46.000000","timezone_type":3,"timezone":"Europe\/Paris"},"url":"\/\/30osd.r.a.d.sendibm1.com\/mk\/mr\/kwK4UoPBwpKUgtMy3RrTs3Fn0Zn0hb4lTgoZcAqRkeWesC3OtK_zelPOf4zHvGR7XP1gto1uuSmJUtNuOUTFtcLqgnHofc_mOiocZLAtwg5XdfRW"}];
return (
<table>
<thead>
<tr>
<th>Elements</th>
<th>Contenu</th>
</tr>
</thead>
<tbody>
{elements.map(element => {
<tr>
<td>
<p>{element.id}</p>
</td>
<td>
<p>{element.url}</p>
</td>
</tr>
})}
</tbody>
</table>
);
}
}
Why nothing is printed inside the tbody of the table ?
I don't know why I'm over it for 2 hours
I want one tr per element and also in each tr have one td for element.id and one for element.url
Inside tbody it should be:
<tbody>
{elements.map(element => {
return <tr>
<td>
<p>{element.id}</p>
</td>
<td>
<p>{element.url}</p>
</td>
</tr>
})}
</tbody>
Try wrapping your elements in parentheses.
An alternative to Sakshi's answer would be:
{
elements.map((element) => (
<tr>
<td>
<p>{element.id}</p>
</td>
<td>
<p>{element.url}</p>
</td>
</tr>
));
}
Make sure you return the JSX elements in your array's .map(). You can use implicit or explicit return:
<tbody>
{elements.map((element) => (
<tr>
<td>
<p>{element.id}</p>
</td>
<td>
<p>{element.url}</p>
</td>
</tr>
))}
</tbody>
Or:
<tbody>
{elements.map((element) => {
return (
<tr>
<td>
<p>{element.id}</p>
</td>
<td>
<p>{element.url}</p>
</td>
</tr>
);
})}
</tbody>
first remove the JSX.Element from the render method as it's not needed if you've created your app with npm create, the main thing is that you need to return your table row inside map function(you only have one row at the moment).
import React from 'react';
export default class HelloWorld extends React.Component {
render(){
let elements = [{"id":1,"isActive":true,"object":"Communication","preview":"Un appercu de la communication","sentAt":{"date":"2020-12-17 15:18:46.000000","timezone_type":3,"timezone":"Europe\/Paris"},"url":"\/\/30osd.r.a.d.sendibm1.com\/mk\/mr\/kwK4UoPBwpKUgtMy3RrTs3Fn0Zn0hb4lTgoZcAqRkeWesC3OtK_zelPOf4zHvGR7XP1gto1uuSmJUtNuOUTFtcLqgnHofc_mOiocZLAtwg5XdfRW"}];
return (
<table>
<thead>
<tr>
<th>Elements</th>
<th>Contenu</th>
</tr>
</thead>
<tbody>
{elements.map(element => {
return(
<tr>
<td>
<p>{element.id}</p>
</td>
<td>
<p>{element.url}</p>
</td>
</tr>
)
})}
</tbody>
</table>
);
}
}

how to generate unique id for table cells using map

I want to set a unique id for each MenuItem, but I don't know how to do this with map() function nested in another one
<table className={classes.table}>
<thead>
<tr>
<td />
{sit.sit.map(sit => (
<td className={classes.sitCell} align="center" key={sit}>
{sit}
</td>
))}
</tr>
</thead>
<tbody>
{sit.row.map(row => (
<tr key={row}>
<td className={classes.rowCell} align="left">
{row}
</td>
{sit.sit.map(sit => (
<td className={classes.sit} key={(id = id + 1)}>
<MenuItem
id={sitId}
onClick={handleSitClick}
disabled={selected}
className={classes.sit}
/>
</td>
))}
</tr>
))}
</tbody>
</table>
Provided code looks fine for me. You can use uuid or any other similar package to generate keys.
Your question is not fully clear i think its may be help you .
<table className={classes.table }>
<thead>
<tr>
<td></td>
{
sit.sit.map((sit) => (<td className={classes.sitCell} align='center' key={sit}>{sit}</td>))
}
</tr>
</thead>
<tbody>
{
sit.row.map((row,index )=> (
<tr key={index}>
<td className={classes.rowCell} align='left'>{row}</td>
{
sit.sit.map((sit) => (<td className={classes.sit} key={id = id+1}><MenuItem id={sitId} onClick={handleSitClick} disabled={selected} className={classes.sit}></MenuItem></td>))
}
</tr>
))
}
</tbody>
</table>
you can just add (row,index) like this
Ideally you need to use a key which is some kind of unique id from your api response. Check your api response data structure, if it has an unique id, then use it. Else use the map array index.
Like this
<table className={classes.table}>
<thead>
<tr>
<td></td>
{
sit.sit.map((sit) => (<td className={classes.sitCell} align='center' key={sit}>{sit}</td>))
}
</tr>
</thead>
<tbody>
{
sit.row.map(row => (
<tr key={row}>
<td className={classes.rowCell} align='left'>{row}</td>
{
sit.sit.map((sit, index) => (<td className={classes.sit} key={index}><MenuItem id={index} onClick={handleSitClick} disabled={selected} className={classes.sit}></MenuItem></td>))
}
</tr>
))
}
</tbody>
</table>

React JS - How do I optimize render code?

I have this code in my render function, but I have 5 different versions with minor html changes. I made new tables with each of the 5. How would I optimize it so I do not have to repeat a lot of html/js code?
<table>
<thead>
<tr>
<th></th>
<th className='desc-col'>Description</th>
<th className='button-col'>Amount</th>
</tr>
</thead>
<tbody> { this.showData
this.state.data.map((exp) => {
if (exp.typeOfItem === "Asset" && exp.term == "Short-Term" ) {
return <tr>
<td className='counterCell'></td>
<td className='desc-col'>{exp.description}</td>
<td className='button-col'>${exp.amount}</td>
<td className='button-col'>
<Update expense={exp} />
</td>
<td className='button-col'>
<Delete expense={exp} />
</td>
</tr>
}
})
}
</tbody>
</table>
<table>
<thead>
<tr>
<th></th>
<th className='desc-col'>Description</th>
<th className='button-col'>Amount</th>
</tr>
</thead>
<tbody>
{
this.state.data.map((exp) => {
if (exp.typeOfItem === "Asset" && exp.term == "Long-Term" ) {
return <tr>
<td className='counterCell'></td>
<td className='desc-col'>{exp.description}</td>
<td className='button-col'>${exp.amount}</td>
<td className='button-col'>
<Update expense={exp} />
</td>
<td className='button-col'>
<Delete expense={exp} />
</td>
</tr>
}
})
}
</tbody>
</table>
You can pull out your Table in a custom component and pass down the data as props,
Your new component would be,
import React from 'react'
const TableComponent = (props) => (
<table>
<thead>
<tr>
<th></th><th className='desc-col'>Description</th>
<th className='button-col'>Amount</th>
</tr>
</thead>
<tbody>
{
props.data.map((exp) => {
if (exp.typeOfItem === props.typeOfItem && exp.term === props.term ) {
return <tr>
<td className='counterCell'></td>
<td className='desc-col'>{exp.description}</td>
<td className='button-col'>${exp.amount}</td>
<td className='button-col'> <Update expense={exp}/></td>
<td className='button-col'><Delete expense={exp} /></td>
</tr>
}
})
}
</tbody>
</table>
)
export default TableComponent
Now you can render this component by passing props,
<TableComponent data={this.state.data} typeOfItem="Asset" term="Short-Term"/>
<TableComponent data={this.state.data} typeOfItem="Asset" term="Long-Term"/>
Note: If you have any other variable's to be used in Table, do pass them as props and in your TableComponent use them appropriately.
You would be better off splitting the array before the render.
for instance:
const assets = this.state.data.filter(item => item.typeOfItem === "Asset");
const longTerm = [];
const shortTerm = [];
assets.forEach((asset) => {
asset.term = "long" ? longTerm.push(asset) : shortTerm.push(asset);
});
Next you can render it with a component you want
longTerm.map(asset => {
return <MyComponent amount={asset.amount} ... />
})
shortTerm.map(asset => {
return <MyComponent amount={asset.amount} ... />
})
And your component could be
function MyComponent(props) {
return <tr>
<td className='counterCell'></td>
<td className='desc-col'>{props.description}</td>
//rest
</tr>
}
additionally you could make a table component and pass it the collection which calls MyComponent
function TableComponent({collection}) {
return <table>
<thead>
<tr>
<th></th><th className='desc-col'>Description</th>
<th className='button-col'>Amount</th>
</tr>
</thead>
<tbody>
{
collection.map(asset => {
return <MyComponent ....
});
}
</tbody>
</table>
}
and then the initial render would just be
<>
<TableComponent collection={longterm} />
<TableComponent collection={shortterm} />
</>

How to create table with multiline cells in React-bootstrap?

I want to create table where some cells contain several lines.
It's work if I do it:
<Table bordered>
<thead>
<tr>
<th>Date</th>
<th>Analysed ID</th>
<th>Analysed Name</th>
<th>Solve To change</th>
</tr>
</thead>
<tbody>
<tr>
<td rowSpan="3">Date</td>
</tr>
<tr>
<td>ID</td>
<td>Name</td>
<td>Decision</td>
</tr>
<tr>
<td>ID</td>
<td>Name</td>
<td>Decision</td>
</tr>
</tbody>
</Table>
I got it:
Table with multiline cell
And now I want to add my 3 "TR" tags in one component, because after I want use for-cycle to create many such components. But components must return content in one closed tag. I tried to contain my 3 "tr" in one parent "tr", but I got error. What can I do here?
It is not possible to create a React Component that returns three elements without wrapping them in another element, such as a div. Otherwise, you'll get the following error:
A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
Your case here is a bit special, because you cannot have div's as the immediate child of table or tbody, so that's a problem...
What you can do however, is to create a class function that returns an array. Like this:
class MyApp extends React.Component {
getTr = () => {
return [
<tr key={0}>
<td rowSpan="3">Date</td>
</tr>,
<tr key={1}>
<td>ID</td>
<td>Name</td>
<td>Decision</td>
</tr>,
<tr key={2}>
<td>ID</td>
<td>Name</td>
<td>Decision</td>
</tr>
];
}
render() {
return (
<table className="table">
<thead>
<tr>
<th>Date</th>
<th>Analysed ID</th>
<th>Analysed Name</th>
<th>Solve To change</th>
</tr>
</thead>
<tbody>
{this.getTr()}
{this.getTr()}
{this.getTr()}
</tbody>
</table>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
You need to include tr tags in one div tag.
The right way to rowSpan is this:
var MyRow = React.createClass({
render: function () {
return (
<div>
<tr>
<td rowSpan="2">{this.props.item.date}</td>
<td>{this.props.item.data[0].id}</td>
<td>{this.props.item.data[0].name}</td>
<td>{this.props.item.data[0].solve}</td>
</tr>
<tr>
<td>{this.props.item.data[1].id}</td>
<td>{this.props.item.data[1].name}</td>
<td>{this.props.item.data[1].solve}</td>
</tr>
</div>
);
}
});
This is my working example: http://jsfiddle.net/andrea689/e33pd14L/

Categories