Make row of table clickable with Link - javascript

Now there is clickable only a table cell containing an icon, like here at the end:
<Table.Body>
{rows.map((row, rowIndex) => (
<Table.Row key={idList && idList[rowIndex]}>
{emptyFirstHeader && (
<Table.Cell>
<Image
src={row.cells[0]}
/>
</Table.Cell>
)}
{
(emptyFirstHeader ? row.cells.shift() : row,
row.cells.map((cell, cellIndex) => {
if (cell === undefined) {
return null;
}
return (
<Table.Cell key={idList}>
{cell}
</Table.Cell>
);
}))
}
<Table.Cell>
<Link //here is the link done - inside a table cell
to={
entityName &&
`/${entityName}/${idList[rows.indexOf(row)]}`
}>
<Icon name="ellipsis horizontal" />
</Link>
</Table.Cell>
</Table.Row>
))}
</Table.Body>
My goal is to make the whole row clickable (and redirect to that new link). So I've tried to make the row clickable:
<Table.Body>
{rows.map((row, rowIndex) => (
<Table.Row key={idList && idList[rowIndex]}>
{emptyFirstHeader && (
<Table.Cell>
<Image
src={row.cells[0]}
/>
</Table.Cell>
)}
{
(emptyFirstHeader ? row.cells.shift() : row,
row.cells.map((cell, cellIndex) => {
if (cell === undefined) {
return null;
}
return (
<Table.Cell key={idList}>
{cell}
</Table.Cell>
);
}))
}
<Table.Cell>
<Icon name="ellipsis horizontal" />
</Table.Cell>
// moved it outside the Tabel.Cell and now it is inside Table.Row
<Link to={entityName && `/${entityName}/${idList[rows.indexOf(row)]}`}>
</Link>
</Table.Row>
))}
</Table.Body>
But unfortunately it's not working. Is there a way to change it and make the whole row clickable?

Put your <Table.Row> element inside the <Link> element. Doing so will "wrap a <Link> behavior around the <Table.Row>".
I believe this code will solve your problem:
<Table.Body>
{rows.map((row, rowIndex) => (
<Link to={entityName && `/${entityName}/${idList[rows.indexOf(row)]}`}>
<Table.Row key={idList && idList[rowIndex]}>
{emptyFirstHeader && (
<Table.Cell>
<Image src={row.cells[0]} />
</Table.Cell>
)}
{
(emptyFirstHeader ? row.cells.shift() : row, row.cells.map((cell, cellIndex) => {
if (cell === undefined) {
return null;
}
return (
<Table.Cell key={idList}>
{cell}
</Table.Cell>
);
}))
}
<Table.Cell>
<Icon name="ellipsis horizontal" />
</Table.Cell>
</Table.Row>
</Link>
))}
</Table.Body>

Related

Whole page reloading after changing one state

I'm currently building a page with a ton of Charts, and I'm using a Material UI menu to kinda switch around graphs.
When I click on a new MenuItem it changes my part state and displays a new array of components.
My main problem right now is that whenever I click on the button, all the charts do a quick load, but with this amount of charts this is a problem.
I've tried debugging it, but to be honest I couldn't find a problem, all my states are set when they need to be set, and useEffects are running just once on the beginning, so no extra loads.
This is what it looks like:
And this would be the code that I'm currently rendering. If you need any further info from my code just let me know and if you can provide any advice for the improvement of my code I would be glad, thanks.
<>
<div className={classes.actionBar}>
<SelectEstimatedMonthForm />
</div>
<div>
<Card>
<div>
<h1>Gráficos de DRE</h1>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Todos Gráficos</MenuItem>
<MenuItem onClick={handleClose}>
Gráficos DRE Orçamento Evolução
</MenuItem>
<MenuItem onClick={handleClose}>
Gráficos de Evolução Parte 2
</MenuItem>
<MenuItem onClick={handleClose}>
Gráficos de Representatividade
</MenuItem>
</Menu>
</div>
<div>
{chartDataPart?.part1 && part === 1 && values && (
<div>
{chartDataPart?.part1?.map((data) => {
if (data?.type === "bar") {
return (
<div>
{data?.labels && (
<ChartBar
data={data}
text={data?.text}
noLabel={data?.noLabel}
stacked={data?.stacked}
newPlugin={data?.customPlugin}
/>
)}
</div>
);
} else if (data?.type === "pie") {
return (
<div>
{data?.labels && (
<ChartPie text={data?.text} data={data} />
)}
</div>
);
} else if (data?.type === "doughnut") {
return (
<div>
{data?.labels && (
<ChartDoughnut text={data?.text} data={data} />
)}
</div>
);
} else {
return (
<div>
<h1>{data?.text} esta sem type</h1>
</div>
);
}
})}
</div>
)}
{chartDataPart?.part2 && part === 2 && values && (
<div>
{chartDataPart?.part2?.map((data) => {
if (data?.type === "bar") {
return (
<div>
{data?.labels && (
<ChartBar
data={data}
text={data?.text}
noLabel={data?.noLabel}
stacked={data?.stacked}
newPlugin={data?.customPlugin}
/>
)}
</div>
);
} else if (data?.type === "pie") {
return (
<div>
{data?.labels && (
<ChartPie text={data?.text} data={data} />
)}
</div>
);
} else if (data?.type === "doughnut") {
return (
<div>
{data?.labels && (
<ChartDoughnut text={data?.text} data={data} />
)}
</div>
);
} else {
return (
<div>
<h1>{data?.text} esta sem type</h1>
</div>
);
}
})}
</div>
)}
{chartDataPart?.part3 && part === 3 && values && (
<div>
{chartDataPart?.part3?.map((data) => {
if (data?.type === "bar") {
return (
<div>
{data?.labels && (
<ChartBar
data={data}
text={data?.text}
noLabel={data?.noLabel}
stacked={data?.stacked}
newPlugin={data?.customPlugin}
/>
)}
</div>
);
} else if (data?.type === "pie") {
return (
<div>
{data?.labels && (
<ChartPie text={data?.text} data={data} />
)}
</div>
);
} else if (data?.type === "doughnut") {
return (
<div>
{data?.labels && (
<ChartDoughnut text={data?.text} data={data} />
)}
</div>
);
} else {
return (
<div>
<h1>{data?.text} esta sem type</h1>
</div>
);
}
})}
</div>
)}
{chartData && part === 0 && values && (
<div>
{chartData?.map((data) => {
if (data?.type === "bar") {
return (
<div>
{data?.labels && (
<ChartBar
data={data}
text={data?.text}
noLabel={data?.noLabel}
stacked={data?.stacked}
newPlugin={data?.customPlugin}
/>
)}
</div>
);
} else if (data?.type === "pie") {
return (
<div>
{data?.labels && (
<ChartPie text={data?.text} data={data} />
)}
</div>
);
} else if (data?.type === "doughnut") {
return (
<div>
{data?.labels && (
<ChartDoughnut text={data?.text} data={data} />
)}
</div>
);
} else {
return (
<div>
<h1>{data?.text} esta sem type</h1>
</div>
);
}
})}
</div>
)}
</div>
</Card>
</div>
</>
useEffect(() => {
const fetchDreData = async () => {
try {
const res = await http.get(
`call1`
);
const data = await res.data;
const final = data.data;
// console.log(final);
setEstimatedMonths(final);
} catch (e) {
console.log("error", e);
}
};
const fetchProductsData = async () => {
try {
const res = await http.get(
`call2`
);
const data = await res.data;
const final = data.data;
// console.log(res);
setEstimatedProducts(final);
} catch (e) {
console.log("error", e);
}
};
fetchDreData();
fetchProductsData();
// console.log("useffect1");
}, [estimatedMonthContext.monthId]);
useEffect(() => {
if (estimatedProducts && estimatedMonths) {
// console.log("useffect2");
flatData();
}
// productsFlatData();
}, [estimatedProducts, estimatedMonths]);
useLayoutEffect(() => {
// if (values) {
chart();
// console.log("useffect3");
// }
}, [values]);
Something on your page is causing the page to rerender again after load, which would be either a state change or most likely the useEffect.
If you are using useEffect make sure you're doing it correctly by 1. not updating state inside it or 2. returning '[]'.
useEffect(() => {
}, []) // this part here
Along with that you're fetching data from multiple endpoints and each time updating the state every time the data returns, which will cause the page to rerender multiple times. Instead you should move each component to their own respective individual components and fetch their own data individually so they don't affect each other and update the whole page.

React class prop onclick

This is my scenario
<List>
{mainTags.map((mainTagItem) => {
return (
<ListItem onClick={() => { setMainTag(mainTagItem.tag.tagId) }} button className={classes.mainTagItem}>
<div className={classes.mainTagCircle}></div>
<ListItemText
primary={mainTagItem.tag.name}
/>
</ListItem>
)
})}
</List>
when i click on my ListItem ( that becomes selected ) i want the element <div className={classes.mainTagCircle}> has an active class
For Example:
<div classes={{ root: !!listItemSelected ? classes.mainTagCircleActive : classes.mainTagCircle, }}></div>
I have already a method onClick in my ListItem, how can i apply this logic?
given that you have a mainTag state you could compare with your element tagId to define which class to select. If it's the same as your state then active class wil be returned:
<div className={
mainTag === mainTagItem.tag.tagId
? classes.mainTagCircleActive
: classes.mainTagCircle}>
</div>
Solution with a library
You could try with this library clsx. Then do something like this:
function Component() {
const [mainTag, setMainTag] = useState(null);
return (
<List>
{mainTags.map((mainTagItem) => {
return (
<ListItem onClick={() => { setMainTag(mainTagItem.tag.tagId) }} className=
{clsx([classes.mainTagItem, mainTag === mainTagItem.tag.tagId ? :
'activeClass': 'defaultClass' ])}>
<div className={classes.mainTagCircle}></div>
<ListItemText
primary={mainTagItem.tag.name}
/>
</ListItem>
)
})}
</List>
)
}
Solution without libraries
function Component() {
const [mainTag, setMainTag] = useState(null);
return (
<List>
{mainTags.map((mainTagItem) => {
return (
<ListItem onClick={() => { setMainTag(mainTagItem.tag.tagId) }} className={
mainTag === mainTagItem.tag.tagId
? classes.mainTagCircleActive
: classes.mainTagCircle}
/>
</ListItem>
)
})}
</List>
)
}

React Native, unable to scroll flatList

I created a flatList but it's not scrolling, I'm just rendering it inside View, below is code. I tried to remove View and just render it inside if else but still not scrolling Can some please tell me why it's not scrolling
else {
return (
<View>
{!this.state.isClicked ? (
<FlatList
style={{marginTop: moderateScaleVertical(10)}}
numColumns={1}
data={this.state.industry}
keyExtractor={(industry) => industry.id.toString()}
renderItem={({item}) => (
<SurveyCard
topText={item.topText}
time={item.time}
title={item.title}
date={item.date}
price={item.price}
off={item.off}
image={item.image}
progress={item.progress}
onPress={() => this.props.navigation.navigate(item.onPress)}
/>
)}
/>
) : (
<FlatList
style={styles.industry}
data={this.state.industry}
key={this.state.horizontal ? 'h' : 'v'}
numColumns={2}
keyExtractor={(industry) => industry.id.toString()}
renderItem={({item}) => (
<SurveyCardRow
topText={item.topText}
time={item.time}
title={item.title}
date={item.date}
price={item.price}
off={item.off}
image={item.image}
onPress={() => this.props.navigation.navigate(item.onPress)}
/>
)}
/>
)}
</View>
);
}

React Error: Each child in a list should have a unique key prop

What's wrong with the following:
<List>
{sections.map(section => (
<>
{section.header && <ListSubheader key={section.header}>{section.header}</ListSubheader>}
{section.items
.filter(item => new RegExp(itemsFilter, 'i').test(item.value))
.map(item => {
const labelId = `multi-select-filter-list-checkbox-label-${item.key}`;
return (
<ListItem key={item.key} role={undefined} dense button onClick={handleToggle(item)}>
<ListItemIcon>
<Checkbox
className={checkboxClasses.root}
edge="start"
checked={checked.indexOf(item) !== -1}
tabIndex={-1}
disableRipple
color="primary"
inputProps={{ 'aria-labelledby': labelId }}
/>
</ListItemIcon>
<ListItemText
id={labelId}
primary={item.value}
primaryTypographyProps={{
variant: 'body1'
}}
/>
</ListItem>
);
})
}
</>
))}
</List>
I believe I'm providing the keys; where is the error?
The key prop should be provided for the wrapping tag.
Replace <> with <React.Fragment> and apply a key to it.
<React.Fragment key={section.header}>
As kind-user user stated you should add key to the wrapping tag.
Key is the only attribute that can be passed to .
Note: When you are passing a key to <>, you can't use this shorthand.
Rather use
<React.Fragment key={yourKey}>
...
<React.Fragment>

material ui SingleExpand TreeView property?

I want to prevent that when I click on several items, I have several items (expand: "true")
I would like that when I click on a new item, the old one goes back to its original state (expand: "false")
However, I did not find any property in the documentation to handle this.
https://material-ui.com/components/tree-view/
{stoMenu && (
<TreeView
style={layout.menu}
defaultCollapseIcon={<KeyboardArrowUpIcon />}
defaultExpandIcon={<KeyboardArrowDownIcon />}
>
{stoMenu.root.children.map(menu => {
return (
<TreeItem
key={menu.nodeId}
nodeId={menu.nodeId}
label={
<ListItem
style={layout.menuListItem}
className={menu.iconCls}
>
<ListItemText
style={layout.menuText}
primary={menu.text}
onClick={() => {
if (menu.id === '/accueil') {
this.props.history.push(menu.id);
}
}}
/>
</ListItem>
}
>
{menu.children.map(child => {
return (
<TreeItem
// style={layout.subMenuText}
className={classes.subMenu}
key={child.nodeId}
nodeId={child.nodeId}
label={child.text}
onClick={() => {
if (child.id) {
this.props.history.push(child.id);
}
}}
/>
);
})}
</TreeItem>
);
})}
</TreeView>
)}

Categories