Problem with accessing an atributes of an object i got from backend - javascript

Problem is in this code:
import React from 'react';
import { Card, CardActions, CardContent, CardMedia, Button, Typography, ButtonBase } from '#material-ui/core/';
import DeleteIcon from '#material-ui/icons/Delete';
import MoreHorizIcon from '#material-ui/icons/MoreHoriz';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { deleteBook } from '../../../../actions/books';
import useStyles from "./styles";
const Book = (book, setCurrentId) => {
const dispatch = useDispatch();
const classes = useStyles();
const user = JSON.parse(localStorage.getItem('profile'));
const history = useHistory();
console.log(book);
const openBook = (e) => {
history.push(`/books/${book._id}`);
};
return (
<Card className={classes.card} raised elevation={6}>
<ButtonBase
component="span"
name="test"
className={classes.cardAction}
onClick={openBook}
>
<CardMedia className={classes.media} image={book.slika || 'https://user-images.githubusercontent.com/194400/49531010-48dad180-f8b1-11e8-8d89-1e61320e1d82.png'} title={book.ime_knjige} />
{(user!= null && user.result.admin_stranice === true) && (
<div className={classes.overlay2} name="edit">
<Button
onClick={(e) => {
e.stopPropagation();
setCurrentId(book._id);
}}
style={{ color: 'white' }}
size="small"
>
<MoreHorizIcon fontSize="default" />
</Button>
</div>
)}
<Typography className={classes.title} gutterBottom variant="h5" component="h2">{book.ime_knjige}</Typography>
<Typography className={classes.title} gutterBottom variant="h5" component="h2">{book.autor_knjige}</Typography>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">{book.opis_knjige && book.opis_knjige.split(' ').splice(0, 20).join(' ')}...</Typography>
<Typography variant="body2" color="textSecondary" component="p> {book.rejting}</Typography>
</CardContent>
<div className={classes.details}>
<Typography variant="body2" color="textSecondary" component="h2 {book.zanr && book.zanr.map((zanr) => `#${zanr} `)}</Typography>
</div>
</ButtonBase>
<CardActions className={classes.cardActions}>
{(user && user.result.admin_stranice === true) && (
<Button size="small" color="secondary" onClick={() => dispatch(deleteBook(book._id))}>
<DeleteIcon fontSize="small" /> Delete
</Button>
)}
</CardActions>
</Card>
);
};
export default Book;
The object "book" i pass here is defined and have all the atributes needed and their values. I used console.log to see object in console and it's there, with everything it should have. But when i try to access any of atributes the JavaScript sees them as undefined for some reason. Some idea why it does that?

Related

Can a component change the data of another component?

I have a component, GameGrid which makes an axios call to get the data that I pass as props to another component, GameCard. I currently have a Header component that is in the same file as GameGrid. The header has buttons which when clicked, changes the endpoint that the GameGrid is calling. I am trying to figure out a way to separate the two components, Header and GameGrid, but still have the buttons on the header determine which endpoint the GameGrid should call. Also, is the GameGrid the right place to have the data being called?
GameGrid.jsx
import React, { useEffect, useState } from "react";
import AppBar from '#mui/material/AppBar';
import Toolbar from '#mui/material/Toolbar';
import Box from '#mui/material/Box';
import IconButton from '#mui/material/IconButton';
import Grid from '#mui/material/Grid';
import axios from "axios";
import GameCard from "./GameCard";
export default function GameGrid() {
const [data, setData] = useState(); // Data Hook
const [route, setRoute] = useState('/')
useEffect(() => {
const getData = async () => {
try {
const { data } = await axios.get(`${process.env.REACT_APP_URL}${route}`);
console.log(data);
setData(data);
} catch (err) {
console.log(err);
}
};
getData();
}, [route]);
const createCards = (data) => {
return <GameCard
key = {data.id}
id = {data.id}
url = {data.game_url}
thumbnail = {data.thumbnail}
title = {data.title}
platform = {data.platform}
description = {data.short_description}
genre = {data.genre}
publisher = {data.publisher}
developer = {data.developer}
/>;
}
const Header = () => {
return (
<Box sx ={{ flexGrow: 1 }}>
<AppBar position="fixed">
<Toolbar>
<Grid sx={{ flexGrow: 1,
border: '1px solid white'}} container spacing={2}>
<Grid sx={{
}}>
<IconButton onClick={() => setRoute('/')}>
<img src='computer-mouse.png' alt='Logo' id='icon'/>
</IconButton>
<IconButton onClick={() => setRoute('/shooter')}>
<img src="shooter.png" alt="Shooter Games" />
</IconButton>
</Grid>
<Grid>
</Grid>
</Grid>
</Toolbar>
</AppBar>
</Box>
)
}
return (
<>
<Header/>
<div className="card-container">
{data?.map(createCards)}
</div>
</>
)
}
GameCard.jsx
import React from "react";
import Card from "#mui/material/Card";
import CardContent from "#mui/material/CardContent";
import CardMedia from "#mui/material/CardMedia";
import Typography from "#mui/material/Typography";
import { CardActionArea, Chip } from "#mui/material";
import Stack from '#mui/material/Stack';
export default function GameCard(props) {
return (
<Card sx={{ width: 550, margin: 2}} key={props.id} id={props.id} >
<CardActionArea href={props.url}>
<CardMedia
component="img"
height="fit-content"
image={props?.thumbnail}
/>
<CardContent>
<Stack direction="row" justifyContent="space-between">
<Typography gutterBottom variant="h6" component="div">
{props.title}
</Typography>
<Chip label={props.platform} size="small"/>
</Stack>
<Typography gutterBottom variant="body1" id="description-text"
color="text.secondary"
sx={{
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap'
}}>
{props.description}
</Typography>
<Stack direction="row" justifyContent="space-between">
<Chip label={props.genre} size="small" />
<Chip label={props.publisher} size="small" />
<Chip label={props.developer} size="small" />
</Stack>
</CardContent>
</CardActionArea>
</Card>
);
}
To separate Header, simply define it with all the props it requires. In this instance, that appears to be the setRoute function though you can call it whatever you like.
For example
// Header.jsx
const Header = ({ onRouteClick }) => (
<Box sx={{ flexGrow: 1 }}>
{/* ... */}
<IconButton onClick={() => onRouteClick("/")}>
<img src="computer-mouse.png" alt="Logo" id="icon" />
</IconButton>
<IconButton onClick={() => onRouteClick("/shooter")}>
<img src="shooter.png" alt="Shooter Games" />
</IconButton>
{/* ... */}
</Box>
);
export default Header;
and in your GameGrid component, import Header from "./Header" and use...
<Header onRouteClick={setRoute} />
If you were using Typescript (highly recommended), the API for Header would look something like this
interface HeaderProps {
onRouteClick: (route: string) => void;
}
const Header = ({ onRouteClick }: HeaderProps) => (
// ...
);

Cannot read properties of null (reading 'result') error in my comments section implementation function

In my application, I have a Meal object that has a comment section attached to it. I get an error when trying to make a comment. There is the code:
import React, { useState } from 'react';
import { Card, CardActions, CardContent, CardMedia, Button, Typography } from '#material-ui/core/';
import ThumbUpAltIcon from '#material-ui/icons/ThumbUpAlt';
import DeleteIcon from '#material-ui/icons/Delete';
import MoreHorizIcon from '#material-ui/icons/MoreHoriz';
import ThumbUpAltOutlined from '#material-ui/icons/ThumbUpAltOutlined';
import moment from 'moment';
import {useDispatch, useSelector} from 'react-redux';
import { Modal, Box, TextField } from "#material-ui/core";
import useStyles from './styles';
import {deleteMeal, getMeals, likeMeal} from '../../../actions/meals';
import { postCommentOnMeal } from '../../../actions/workouts';
const Meal=({meal, setCurrentId})=> {
const classes=useStyles();
const dispatch=useDispatch();
const user = JSON.parse(localStorage.getItem('profile'));
const Likes = () => {
if (meal.likes && meal.likes.length > 0) {
return meal.likes.find((like) => like === (user?.result?.googleId || user?.result?._id))
? (
<><ThumbUpAltIcon fontSize="small" /> {meal.likes.length > 2 ? `You and ${meal.likes.length - 1} others` : `${meal.likes.length} like${meal.likes.length > 1 ? 's' : ''}` }</>
) : (
<><ThumbUpAltOutlined fontSize="small" /> {meal.likes.length} {meal.likes.length === 1 ? 'Like' : 'Likes'}</>
);
}
return <><ThumbUpAltOutlined fontSize="small" /> Like</>;
};
const [open, setOpen] = React.useState(false);
const [currentMeal, setcurrentMeal] = React.useState("");
const handleOpen = (id) => {
setcurrentMeal(id);
setOpen(true);
};
const handleClose = () => setOpen(false);
const [comment, setComment] = useState("");
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "background.paper",
border: "2px solid #000",
boxShadow: 24,
p: 4,
};
const currentUser = useSelector((state) => state.auth);
function addComment() {
const data = {
comment,
userId: currentUser.authData.result._id,
userName: currentUser.authData.result.name,
mealId: currentMeal,
};
dispatch(postCommentOnMeal(data));
dispatch(getMeals());
handleClose();
}
function getComments() {
return (
<>
{meal && meal.comments.length > 0
? meal.comments.map((item) => {
return (
<div
style={{
marginTop: 10,
backgroundColor: "grey",
padding: 2,
borderRadius: 4,
}}
>
<h5 style={{ marginBottom: -10 }}>{item.commentor}</h5>
<p>{item.comment}</p>
</div>
);
})
: "No comments yet"}
</>
);
}
return (
<>
<Card className={classes.card}>
<CardMedia className={classes.media} image={meal.selectedFile|| 'https://user-images.githubusercontent.com/194400/49531010-48dad180-f8b1-11e8-8d89-1e61320e1d82.png'} title={meal.category}/>
<div className={classes.overlay}>
<Typography variant="h6">{meal.calories}</Typography>
<Typography variant="body2">{moment(meal.createdAt).fromNow()}</Typography>
</div>
{(user?.result?.googleId===meal?.creator || user?.result?._id===meal?.creator) && (
<div className={classes.overlay2}>
<Button style={{color:'white'}} size="small" onClick={()=>{
setCurrentId(meal._id)
}}>
<MoreHorizIcon fontSize="medium"/>
</Button>
</div>
)}
<div className={classes.details}>
<Typography className={classes.title} gutterBottom variant="h5" component="h2">{meal.name}</Typography>
</div>
<Typography className={classes.difficulty} variant="body2" color="textSecondary" component="p">{meal.category}</Typography>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">{meal.calories}</Typography>
</CardContent>
<CardActions className={classes.cardActions}>
<Button size='small' color="primary" disabled={!user?.result} onClick={()=>{dispatch(likeMeal(meal._id))}}>
<Likes/>
</Button>
<Button
size="small"
color="primary"
disabled={!user?.result}
onClick={() => {
handleOpen(meal._id);
}}
>
Comments
</Button>
{(user?.result?.googleId===meal?.creator || user?.result?._id===meal?.creator) && (
<Button size='small' color="primary" onClick={()=>{dispatch(deleteMeal(meal._id))}}>
<DeleteIcon fontSize="small"/>
Delete
</Button>
)}
</CardActions>
</Card>
<Modal
className={classes.modal}
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
{getComments()}
<TextField
margin="normal"
name="comment"
variant="outlined"
label="Comment"
fullWidth
value={comment}
onChange={(e) => {
setComment(e.target.value);
}}
/>
<Button
margin="normal"
variant="contained"
color="primary"
onClick={addComment}
>
POST
</Button>
</Box>
</Modal>
</>
);
}
export default Meal;
The error occurs at this line: userId: currentUser.authData.result._id, in the addComment() function and it says: Uncaught TypeError: Cannot read properties of null (reading 'result').
Could you help me?

when I type my react js component it is doing well but when i reload the browser it gives me error Cannot read property 'value' of undefined

this is App js
import React from "react"
import React from "react"
import {Cards , Chart , CountryPicker} from "./Components"
import styles from "./App.module.css"
import {fetchData} from "./api"
class App extends React.Component{
state = {
data : {},
}
async componentDidMount() {
const fetchedData = await fetchData()
this.setState({data : fetchedData})
}
render() {
return (
<div className={styles.container}>
<Cards data={this.state.data}/>
<CountryPicker />
<Chart />
</div>
)
}
}
export default App
'''
and this is Card component
import React from "react"
import {Card, CardContent, Typography, Grid} from '#material-ui/core'
import styles from "./Cards.module.css"
import CountUp from "react-countup"
const Cards = (props) => {
console.log(props)
return (
<div className={styles.container}>
<Grid container spacing={3} justify="center">
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Infected</Typography>
<Typography variant="h5"><CountUp start={0} end={props.data.confirmed.value} separator="," duration={2} /></Typography>
<Typography color="textSecondary">{new Date(props.data.lastUpdate).toDateString()}</Typography>
<Typography variant="body2">Number of Active cases of Covid-19</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Recovered</Typography>
<Typography variant="h5"><CountUp start={0} end={props.data.recovered.value} separator="," duration={2} /></Typography>
<Typography color="textSecondary">{new Date(props.data.lastUpdate).toDateString()}</Typography>
<Typography variant="body2">Number of Recoveries from Covid-19</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Deaths</Typography>
<Typography variant="h5"><CountUp start={0} end={props.data.deaths.value} separator="," duration={2} /></Typography>
<Typography color="textSecondary">{new Date(props.data.lastUpdate).toDateString()}</Typography>
<Typography variant="body2">Number of Deaths caused by Covid-19</Typography>
</CardContent>
</Grid>
</Grid>
</div>
)
}
export default Cards
'''
You can use optional chaining to check if you have data in your object.
So try something like below:-
// add optional chaining for below
props.data.confirmed.value => props.data.confirmed?.value
props.data.recovered.value => props.data.recovered?.value
props.data.deaths.value => props.data.deaths?.value
Because the initial state is undefined. Put your code inside an if statement so it doesn't give an error.
<div className={styles.container}>
if(this.state) {
<Cards data={this.state.data}/>
} else {
<p>Loading data...</p>
}
<CountryPicker />
<Chart />
</div>

Why 1 value from API doesn't not save?

API this one https://covid19.mathdro.id/api
Sorry for interrupt, but I freaking out with this issue, almost 2 hours im thinking what the problem.
So, for recored and for confirmed it works fine, but for deaths I have this issue:
Issue photo
import React from 'react';
import {Card, CardContent, Typography, Grid} from '#material-ui/core';
import CountUp from 'react-countup';
import cx from 'classnames';
import styles from './Cards.module.css'
const Cards = ({data: {deaths, confirmed, recovered, lastUpdate } } ) => {
if(!confirmed) {
return 'Loading...'
};
return (
<div className={styles.container}>
<Grid container spacing={3} justify="center">
<Grid item component={Card} xs={12} md={3} className={cx(styles.card, styles.infected)}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Infected</Typography>
<Typography variant="h5">
<CountUp
start={0}
end={confirmed.value}
duration={2.5}
separator=","
/>
</Typography>
<Typography color="textSecondary">{new Date(lastUpdate).toDateString()}</Typography>
<Typography variant="body2">Number of active cases</Typography>
</CardContent>
</Grid>
<Grid item component={Card} xs={12} md={3} className={cx(styles.card, styles.recovered)}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Recovered</Typography>
<Typography variant="h5">
<CountUp
start={0}
end={recovered.value}
duration={2.5}
separator=","
/>
</Typography>
<Typography color="textSecondary">{new Date(lastUpdate).toDateString()}</Typography>
<Typography variant="body2">Number of recoveries from COVID-19</Typography>
</CardContent>
</Grid>
<Grid item component={Card} xs={12} md={3} className={cx(styles.card, styles.deaths)}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Deaths</Typography>
<Typography variant="h5">
<CountUp
start={0}
end={deaths.value}
duration={2.5}
separator=","
/>
</Typography>
<Typography color="textSecondary">{new Date(lastUpdate).toDateString()}</Typography>
<Typography variant="body2">Number of deaths caused by COVID-19</Typography>
</CardContent>
</Grid>
</Grid>
</div>
)
}
export default Cards;
this is my app.js
import React from 'react';
import { Cards, Chart, CountryPicker } from './components';
import styles from './App.module.css';
import { fetchData } from './api';
class App extends React.Component {
state = {
data: {},
}
async componentDidMount() {
const fetchedData = await fetchData();
this.setState({ data: fetchedData });
}
render() {
const {data} = this.state;
return (
<div className={styles.container}>
<Cards data={data}/>
<Chart />
<CountryPicker />
</div>
)
}
}
export default App;
So, I'm try without deaths and it works, but with not.
index.js
import axios from 'axios';
const url = 'https://covid19.mathdro.id/api';
export const fetchData = async () => {
try {
const { data: { confirmed, recovered, death, lastUpdate } } = await axios.get(url);
return {confirmed, recovered, death, lastUpdate};
} catch (error) {
}
}
Thanks for helping me out!
You have missed a "s" (it is deaths not death, according to the API) in your fetch data function.
Update your this part
data: { confirmed, recovered, death, lastUpdate } } = await axios.get(url);
to
data: { confirmed, recovered, deaths, lastUpdate } } = await axios.get(url);
:D

React - Can't find the leak, infinite state declaration suspected

I'm a complete beginner in React and I was pretty happy with my first app since I, maybe, have a memory leak ? My app is very laggy after entering value in the input, after click on the add button, at bottom right, and I suspect that I don't use 'useState' like I should ? I dunno, I've been searching for hours :( ...
Here's the app : https://n3g.gitlab.io/react-conso-energie/
Here's the code :
In the App.js (parent) :
import React, { useState } from 'react'
import firebase from './firebase'
import AddForm from './AddForm'
import ListingTable from './ListingExpansionPanels'
import moment from 'moment'
// MATERIAL UI
import { CssBaseline } from '#material-ui/core'
import Grid from '#material-ui/core/Grid'
import Snackbar from '#material-ui/core/Snackbar'
import MuiAlert from '#material-ui/lab/Alert'
import './styles.css'
export default function App () {
// BDD
const dbRef = firebase.database().ref('items')
// LISTING DATA
const [listingData, setListingData] = useState([{}])
dbRef.once('value', (snapshot) => {
const releves = snapshot.val()
const listingData = []
for (const [key, releve] of Object.entries(releves)) {
listingData.push({
key: key,
month: releve.month,
gaz: releve.gaz,
electricite: releve.electricite,
total: releve.total,
submissionDate: releve.submissionDate
})
}
const listingDataSorted = listingData.sort((a, b) => (a.submissionDate > b.submissionDate) ? 1 : -1)
setListingData(listingDataSorted)
})
const lastItemIndex = listingData.length - 1
// MONTHS
const [selectedDate, handleDateChange] = useState(new Date())
const dateFormat = moment(selectedDate).format('MMMM')
// ELECTRICITÉ
const constElec = { prix: 0.15356, abo: 117.56 }
const [kw, setKw] = useState('')
const diffElec = kw - listingData[lastItemIndex].electricite
const resultatElec = Math.round((constElec.prix * diffElec + (constElec.abo / 12)) * 1e2) / 1e2
// GAZ
const constGaz = { prix: 0.0681, abo: 215.73, indice: 11.34 }
const [m3, setm3] = useState('')
const diffGaz = m3 - listingData[lastItemIndex].gaz
const resultatGaz = Math.round((((constGaz.indice * diffGaz) * constGaz.prix) + (constGaz.abo / 12)) * 1e2) / 1e2
// TOTAL
const total = Math.round((resultatElec + resultatGaz) * 1e2) / 1e2
// SUBMIT
const handleSubmit = () => {
const releve = {
submissionDate: moment(selectedDate).unix(),
month: dateFormat,
gaz: m3,
electricite: kw,
total: total
}
dbRef.push(releve)
setOpenSnack(true)
setm3('')
setKw('')
}
// DELETE
const handleDelete = key => {
dbRef.child(key).remove()
}
// SNACKBAR
function Alert (props) {
return <MuiAlert elevation={6} variant='filled' {...props} />
}
const [openSnack, setOpenSnack] = React.useState(false)
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpenSnack(false)
}
return (
<>
<CssBaseline />
<div className='App'>
<Grid container justify='center' spacing={2}>
<Grid item xs={12}>
<h1>Conso Energie</h1>
<AddForm m3={m3} setm3={setm3} kw={kw} setKw={setKw} selectedDate={selectedDate} handleDateChange={handleDateChange} handleSubmit={handleSubmit} />
</Grid>
<Grid item xs={12}>
<ListingTable listingData={listingData} handleDelete={handleDelete} />
</Grid>
</Grid>
<Snackbar open={openSnack} autoHideDuration={3500} onClose={handleClose}>
<Alert onClose={handleClose} severity='success'>
Sauvegardé
</Alert>
</Snackbar>
</div>
</>
)
}
In the AddForm.js (child - I'm using Material UI) :
import React from 'react'
import TextField from '#material-ui/core/TextField'
import InputAdornment from '#material-ui/core/InputAdornment'
import Button from '#material-ui/core/Button'
import CloudUploadIcon from '#material-ui/icons/CloudUpload'
import { MuiPickersUtilsProvider, DatePicker } from '#material-ui/pickers'
import MomentUtils from '#date-io/moment'
import moment from 'moment'
import 'moment/locale/fr'
import Dialog from '#material-ui/core/Dialog'
import DialogActions from '#material-ui/core/DialogActions'
import DialogContent from '#material-ui/core/DialogContent'
import DialogTitle from '#material-ui/core/DialogTitle'
import Fab from '#material-ui/core/Fab'
import AddIcon from '#material-ui/icons/Add'
export default function AddForm ({ m3, setm3, kw, setKw, handleSubmit, selectedDate, handleDateChange }) {
const handleUpdateGaz = function (event) {
setm3(Number(event.target.value))
}
const handleUpdateKw = function (event) {
setKw(Number(event.target.value))
}
moment.locale('fr')
const [open, setOpen] = React.useState(false)
const handleClickOpenAddDialog = () => {
setOpen(true)
}
const handleCloseAddDialog = () => {
setOpen(false)
}
return (
<>
<div>
<Fab className='fab-btn-add' color='primary' aria-label='add' onClick={handleClickOpenAddDialog}>
<AddIcon />
</Fab>
<Dialog
open={open}
onClose={handleCloseAddDialog}
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle id='alert-dialog-title'>Entrer les valeurs</DialogTitle>
<DialogContent>
<form className='addform' noValidate autoComplete='off'>
<MuiPickersUtilsProvider utils={MomentUtils}>
<DatePicker
inputVariant='outlined'
value={selectedDate}
onChange={handleDateChange}
label='Mois'
format='MMMM Y'
views={['month']}
minDate={new Date('2020-01-01')}
maxDate={new Date('2020-12-31')}
/>
</MuiPickersUtilsProvider>
<TextField
label='Electricité'
variant='outlined'
type='number'
InputProps={{
endAdornment: <InputAdornment position='end'>kW</InputAdornment>
}}
value={kw}
onChange={handleUpdateKw}
/>
<TextField
label='Gaz'
variant='outlined'
type='number'
InputProps={{
endAdornment: <InputAdornment position='end'>m3</InputAdornment>
}}
value={m3}
onChange={handleUpdateGaz}
/>
<Button
className='btn-submit'
size='large'
variant='contained'
color='primary'
startIcon={<CloudUploadIcon />}
onClick={handleSubmit}
>
Confirmer
</Button>
</form>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseAddDialog} color='primary' autoFocus>
Retour
</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
Pretty sure it's unrelated but here's the ListingExpansionPanel.js
import React from 'react'
import ExpansionPanel from '#material-ui/core/ExpansionPanel'
import ExpansionPanelSummary from '#material-ui/core/ExpansionPanelSummary'
import ExpansionPanelDetails from '#material-ui/core/ExpansionPanelDetails'
import Typography from '#material-ui/core/Typography'
import ExpandMoreIcon from '#material-ui/icons/ExpandMore'
import Icon from '#material-ui/core/Icon'
import Grid from '#material-ui/core/Grid'
import Button from '#material-ui/core/Button'
import Chip from '#material-ui/core/Chip'
import SwipeableViews from 'react-swipeable-views'
export default function ListingTable ({ listingData, handleDelete }) {
const dataRow = listingData.map((data, key) => (
<ExpansionPanel key={key} className='relevePanel'>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={key}
id={key}
>
<Typography>
<span>
<Icon style={{ marginRight: 15 }}>calendar_today</Icon>
{data.month}<b>{data.total ? ' : ' + data.total + ' €' : ''}</b>
</span>
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<SwipeableViews>
<Typography className='expansion-detail'>
<Grid container>
<Grid item xs={12}>
<b style={{ color: '#cacaca' }}>2020</b>
</Grid>
<Grid item xs>
<Icon>power</Icon>
<span>{data.electricite} <small>Kwh</small></span>
<div>
<Chip className='plus' size='small' label='+3,4%' />
</div>
</Grid>
<Grid item xs>
<Icon>whatshot</Icon>
<span>{data.gaz} <small>m<sup>3</sup></small></span>
<div>
<Chip className='moins' size='small' label='-5,2%' />
</div>
</Grid>
<Grid item xs={12}>
<Button
className='btnRemove'
style={{ marginTop: 15 }}
size='small'
color='secondary'
onClick={() => handleDelete(data.key)}
>
Supprimer
</Button>
</Grid>
</Grid>
</Typography>
<Typography className='expansion-detail'>
<Grid container>
<Grid item xs={12}>
<b style={{ color: '#cacaca' }}>2019</b>
</Grid>
<Grid item xs>
<Icon>power</Icon>
<span>{data.electricite} <small>Kwh</small></span>
<div>
<Chip className='plus' size='small' label='+3,4%' />
</div>
</Grid>
<Grid item xs>
<Icon>whatshot</Icon>
<span>{data.gaz} <small>m<sup>3</sup></small></span>
<div>
<Chip className='moins' size='small' label='-5,2%' />
</div>
</Grid>
<Grid item xs={12}>
<Button
className='btnRemove'
style={{ marginTop: 15 }}
size='small'
color='secondary'
onClick={() => handleDelete(data.key)}
>
Supprimer
</Button>
</Grid>
</Grid>
</Typography>
</SwipeableViews>
</ExpansionPanelDetails>
</ExpansionPanel>
))
return (
<>
{dataRow}
</>
)
}
Thank you A LOT for your help, if someone see something.
I continue to search..
Thanks.
Update : Added the whole code for this 2 files
Update 2 : When I disable the firebase link, it's ok ! So I'll investigate this way..
This won't solve your problem but one thing that will use less memory is not creating an anonymous function, but replacing it with a reference in child components.
In the AddForm.js :
// pass the reference to changeKw instead of creating an anonymous function:
<TextField
value={kw}
onChange={changeKw} // e will be passed automatically
/>
In the App.js (parent) :
const changeKw = e => {
console.log(e.target.value) // e gets passed
setKw(e.target.value)
}

Categories

Resources