passing props for components to useMemo getting undefine - javascript

I am passing data in the MemoDownloadsSubTab component but when I am trying to use it in MemoDownloadsSubTab in useMemo I am getting error data that is not defined I am not sure why this is happening let me know what I need to change so any another way I need to pass data in parent to child and us in the child component.
export const CorporateDetailsTable = ({
userHistorySummary,
}) => {
const MemoDownloadsSubTab = React.useMemo(
({ data = [] }) => {
return (
<>
{data?.length !== 0 &&
data?.map((row, rowIndex) => {
return (
<Box bgcolor="mainDetailsCard.primary" m={1} p={1} borderRadius={5}>
<Grid xs={12} item container spacing={2}>
<Grid item xs={12} sm={3}>
<Typography component="div">
<Box fontWeight="fontWeightBold" component="span" mr={1}>
SRN :
</Box>
{row.SRN}
</Typography>
</Grid>
<Grid item xs={12} sm={3}>
<Typography component="div">
<Box fontWeight="fontWeightBold" component="span" mr={1}>
Charge ID :
</Box>
{row.CHARGE_ID ? row.CHARGE_ID : "N/A"}
</Typography>
</Grid>
</Grid>
</Box>
);
})}
</>
);
}
,[userHistorySummary?.charges]);
return (
<>
{userHistorySummary?.masterData?.length !== 0 ? (
<Box mt={1}>
return (
<MemoDownloadsSubTab
data={userHistorySummary?.charges}
title={"Charges Registered"}
cells={chargesCells}
classes={classes}
/>
</Box>
) : (
<Typography variant="subtitle1" color="textSecondary">
No Data Available
</Typography>
)}
</>
);
};

Related

How to show list items after state changes in react-redux

I have a menu bar that shows category of my shop. When I click on a category a product list of that category should be shown on my shop component (also I use redux library). It works correctly for first time, but when I click on another category the state changes and the filter products update too but they don't show on my shop component. I must click a button on page to show updated list in shop component. How can I show them immediately after updating?
App.jsx
<Menubar/>
<Routes>
<Route path='/shopping' element={<Shop />}></Route>
</Routes>
Menubar.jsx
export default function MenuBar() {
const products = useSelector(state=>state.products);
const navigate = useNavigate();
const getCategory = (e) => {
let category = e.target.innerText;
dispatch(filterProByCategory(products, category));
navigate('/shopping');
}
return (
<>
<ul>
<li onClick={(e)=>getCategory(e)}>
Fashion
</li>
</ul>
</>
)
}
Shop.jsx
export default function Shop() {
const products = useSelector(state => state.filters.filterProducts);
const [filterProducts, setFilterproducts] = useState(products);
return (
<>
<Grid item xs={12} md={8} dir='rtl'>
<Card sx={{ minWidth: 275 }}>
<CardContent>
{/* */}
<Grid container spacing={1}>
{filterProducts && filterProducts.map((product, index) => (
<Grid item xs={12} md={4}>
<ProductCard product={product} key={index} />
</Grid>
))}
</Grid>
</>
)
}
Just use the direct result of products instead of using it for creating another state variable filteredProducts with useState
export default function Shop() {
const products = useSelector(state=>state.filters.filterProducts);
// const [filterProducts , setFilterproducts] = useState (products);
return (
<>
<Grid item xs={12} md={8} dir='rtl'>
<Card sx={{ minWidth: 275 }}>
<CardContent>
{/* */}
<Grid container spacing={1}>
{products && products.map((product , index)=>(
<Grid item xs={12} md={4}>
<ProductCard product={product} key={index}/>
</Grid>
))}
</Grid>
</>
)
}

how can i append selected row data in another table

what my task is I am using a table with two different conditions like in the first table whatever data coming I will show that in the first table and in the second table whatever row I select in the first table that I want to show in the second table as the second table I called select summary so my task is in the first table whatever row I selected in need to how that row in the second table I am using same table component for this for better you can see CodeSandBox link
import React, { useState, useMemo, useEffect } from "react";
import {
Grid,
makeStyles,
CardContent,
Card,
Box
} from "#material-ui/core";
import EnhancedTable from "./EnhancedTable";
const useStyles = makeStyles((theme) => ({
root: {
padding: theme.spacing(0, 2, 2),
},
formGrid: {
padding: theme.spacing(2),
},
cardColor: {
borderColor: "#0bb7a7",
},
}));
function AddToExclusionList() {
const classes = useStyles();
const [sanctionsList, setSanctionsList] = useState([]);
const updateListsRow = ({ index, value, row }, listType) => {
switch (listType) {
case "sanctions":
setSanctionsList((prevState) => {
prevState[index].status = value;
return [...prevState];
});
break;
default:
}
};
return (
<Grid className={classes.root}>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<EnhancedTable
show={true}
step="first"
/>
</>
</CardContent>
</Card>
</Grid>
<Box mt={3}></Box>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<h3>summary table</h3>
<EnhancedTable
checkboxToggle={(rowDetails) => {
updateListsRow(rowDetails, "sanctions");
}}
/>
</>
</CardContent>
</Card>
</Grid>
</Grid>
);
}
export default AddToExclusionList;
CodeSandBox Link
You've achieved your goal very weird! Anyway, based on your code in codesandbox. You need to add a state to AddToExclusionList component, like this:
const [newRows, setNewRows] = useState([]);
const setSummaryRows = (selectedRows) => {
const copy = [...rows];
const filteredRows = copy.filter((x) => selectedRows.includes(x.name));
setNewRows(filteredRows);
};
We need the mentioned state to update the summary table's rows.
Also add rows and setNewRows prop to EnhancedTable and give it rows from out of the component. In addition move rows and createData to App.js. So you should use EnhancedTable in App.js same as bellow:
<Grid className={classes.root}>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<h3>first table</h3>
<EnhancedTable
// passing data for rendering table according condition
step="first"
rows={rows}
setNewRows={(selected) => {
setSummaryRows(selected);
}}
/>
</>
</CardContent>
</Card>
</Grid>
<Box mt={3}></Box>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<h3>summary table</h3>
<EnhancedTable
// trying to pasing selected data
rows={newRows}
setNewRows={() => {}}
/>
</>
</CardContent>
</Card>
</Grid>
</Grid>
And the last part is using useEffect based on selected in EnhancedTable component:
useEffect(() => {
setNewRows(selected);
}, [selected]);

How to fix linter expected to return a value at the end of react function component?

I create a function component to render error message, but its has a linter warning "Expected to return a value at the end of function 'renderErrorMessage' consistent-return
function renderError() {
if (errors.file) {
return (
<Grid item>
<Grid container direction="column">
<Grid item>
<Text size="14px" height="1.43" isError>
Error Data :
</Text>
</Grid>
{errors.file.map((message) => (
<Grid item key={message}>
<Text size="12px" isError>
{message}
</Text>
</Grid>
))}
</Grid>
</Grid>
);
}
}
Your function will not return any value if errors.file condition is false, thats why you're getting the warning. You can refactor your component like this:
function renderError() {
if (!errors || !errors.file) {
return null;
}
return (
<Grid item>
<Grid container direction="column">
<Grid item>
<Text size="14px" height="1.43" isError>
Error Data :
</Text>
</Grid>
{errors.file.map((message) => (
<Grid item key={message}>
<Text size="12px" isError>
{message}
</Text>
</Grid>
))}
</Grid>
</Grid>
);
}

Render run twice times

I've a list of countries which i would like show some info related to the country. I run a loop in order to show the info for each country. I've created a component for a country.
const CountryCard = ({ info }) => {
const { country, infoForLastDate, path } = info
return (
<Card >
<CardContent>
<Typography variant="h5" component="h2" >
{country.name}
</Typography>
<Flag oneToOne={country.oneToOne} fourToThree={country.fourToThree} />
<Typography variant="body2" >
Confirmed: {infoForLastDate.confirmed}
</Typography>
<Typography variant="body2" component="p">
Recovered: {infoForLastDate.recovered}
</Typography>
<Typography variant="body2" component="p">
Deaths: {infoForLastDate.deaths}
</Typography>
</CardContent>
<CardActions>
<Link href={path}>
See more
</Link>
</CardActions>
</Card>
)
}
export default CountryCard
Also, I've created another component to show the flag related to the country.
import React from 'react'
import { imageUrlFor } from '../lib/image-url'
const Flag = ({ oneToOne, fourToThree }) => {
const url = imageUrlFor(oneToOne.asset._id)
return (
<img src={url} />
)
}
export default Flag
I get the error TypeError: oneToOne is null
i don't know why it is like the flags render twice times. when I debugged, first time oneToOne property has a value, but at the end is run again and is null
Why is it happens?
Edit: Add CountryList component:
const CountryList = ({list}) => {
return (
<Grid container spacing={3}>
{ list.length > 1 && list.map(country => {
const countryWithPath = {
...country,
path: `/country/${country.country.name.toLowerCase().replace(' ', '-').replace('*', '')}`
}
return (
<Grid item xs={12} sm={6} key={country._id} >
<CountryCard info={countryWithPath} />
</Grid>)
})
}
</Grid>
)
}
export default CountryList

extract object items in object array at react template

I'm newbies in react and javascript. I try to use this below data in react template. They're object array so i want to every items in this object array print separately in HTML (react template). Anyone can help me, i have code below, please help:
const fakeData = [
{
MOP: 'MOP',
code: '#1180-xxxx',
date: '10-08-2018',
status: 'Pending Order',
},
{
MOP: 'MOP1',
code: '#1180-xxxx1',
date: '11-08-2018',
status: 'Pending Order',
},
{
MOP: 'MOP2',
code: '#1180-xxxx2',
date: '12-08-2018',
status: 'Pending Order',
},
];
export class TransactionPage extends React.PureComponent {
constructor(props) {
super(props);
this.state = { fakeData };
}
render() {
const { classes, intl } = this.props;
return (
<Page>
<Helmet>
<title>{intl.formatMessage({ ...messages.header })}</title>
<meta
name="description"
content={<FormattedMessage {...messages.meta} />}
/>
</Helmet>
<PageContent>
<Paper>
<Grid container>
<Grid item xs={12} sm={5} md={4} lg={3}>
<List className={classes.list} disablePadding>
// show the item here
</List>
</Grid>
<Hidden xsDown>
<Grid item sm={7} md={8} lg={9}>
<Grid
container
direction="column"
spacing={16}
className={classes.details}
>
<Grid item xs={12} className={classes.center} />
<Grid item xs={12}>
<Typography variant="h6">CREDIT DEBIT</Typography>
</Grid>
<Grid item xs={12}>
<Divider />
</Grid>
<Grid item xs={12} />
</Grid>
</Grid>
</Hidden>
</Grid>
</Paper>
</PageContent>
</Page>
);
}
}
TransactionPage.propTypes = {
intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
};
const mapStateToProps = createStructuredSelector({
TransactionPage: makeSelectTransactionPage(),
});
function mapDispatchToProps(dispatch) {
return {
dispatch,
};
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);
const withReducer = injectReducer({ key: 'TransactionPage', reducer });
const withSaga = injectSaga({ key: 'TransactionPage', saga });
export default compose(
withStyles(styles),
injectIntl,
withReducer,
withSaga,
withConnect,
)(TransactionPage);
I want this code transform as output below in the page:
<Grid container>
<Grid item xs={12} sm={5} md={4} lg={3}>
<List className={classes.list} disablePadding>
<ListItem button>
<span>MOP</span>
<span>#1180-xxxx</span>
<span>10-08-2018</span>
<span>Pending Order</span>
<ListItemSecondaryAction>
<ArrowIcon />
</ListItemSecondaryAction>
</ListItem>
<ListItem button>
<span>MOP1</span>
<span>#1180-xxxx1</span>
<span>11-08-2018</span>
<span>Pending Order</span>
<ListItemSecondaryAction>
<ArrowIcon />
</ListItemSecondaryAction>
</ListItem>
<ListItem button>
<span>MOP2</span>
<span>#1180-xxxx2</span>
<span>12-08-2018</span>
<span>Pending Order</span>
<ListItemSecondaryAction>
<ArrowIcon />
</ListItemSecondaryAction>
</ListItem>
</List>
</Grid>
i'm using react, how to loop them in react template.
You just create a map with JSX:
<List className={classes.list} disablePadding>
{fakeData.map((item, i) => <ListItem key={item.MOP+"_" + i} button>....</ListItem>) }
</List>
You can map it like this pseudo...
var formatted = fakeData.map((item, idx) => {
return(
<ListItem key={idx}>
<span>{item.MOP}</span>
<span>{item.code}</span>
<span>{item.date}</span>
<span>{item.status}</span>
</ListItem>
)
})
return(
<List>
{formatted}
</List>
)

Categories

Resources