As in object, I’m writing a React app, but cannot figure out why when I click on the card, the first click returns undefined, and then the next click returns the element I clicked on before that. I leave my code here.
app.js calls the main component (I want to make the app component as functional as possible).
import React, { Component } from 'react';
import Main from './components/MainComponent';
class App extends Component {
render() {
return(
<div className='App'>
<Main />
</div>
)
}
}
export default App;
MainComponent.js contains everything logic related (it is still at a very early stage)
import React, { Component } from 'react';
import { Navbar, Icon } from 'react-materialize';
import Dashboard from './DashboardComponent';
import Details from './DetailsComponent';
import { ITEMS } from '../shared/items';
import { SUPPLIERS } from '../shared/suppliers';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
items: ITEMS,
suppliers: SUPPLIERS,
selectedItem: null
};
this.onItemSelect = this.onItemSelect.bind(this);
}
onItemSelect(itemId) {
this.setState({ selectedItem: itemId });
console.log(this.state.items.filter(item => item.id === this.state.selectedItem)[0]);
}
componentDidMount() {
console.log(this.state.selectedItem);
}
render() {
return(
<div>
<Navbar
alignLinks='right'
menuIcon={<Icon>menu</Icon>}
fixed
className='green'
search
>
</Navbar>
<Dashboard items={this.state.items} onClick={(itemId) => this.onItemSelect(itemId)} />
<Details item={this.state.items.filter(item => item.id === this.state.selectedItem)[0]} />
</div>
)
}
}
export default Main;
DashboardComponent.js this is where the problem occurs. Whenever I reload the page, if item is null (which is supposed to be), I get an error of it being undefined. If in the main component I hard code the selected item to be one of the ids (which is a field of items), I get that if I click on a card, I get undefined back. Then if I click on another card, I get back the informations of the one I clicked before that.
import React, { Component } from 'react';
import { Row, Col, Icon, Card, CardTitle, Container } from 'react-materialize';
class Dashboard extends Component {
render() {
const dashboard = this.props.items.map(item => {
return (
<div key={item.id}>
<Col m={6} s={12}>
<Card
actions={[
<a key={item.id} href='#'>Details</a>
]}
onClick={() => this.props.onClick(item.id)}
closeIcon={<Icon>close</Icon>}
header={<CardTitle image="https://materializecss.com/images/sample-1.jpg" />}
horizontal
revealIcon={<Icon>more_vert</Icon>}
title={item.name}
>
</Card>
</Col>
</div>
);
});
return(
<Container>
<Row>
{dashboard}
</Row>
</Container>
);
}
}
export default Dashboard;
DetailsComponent.js is what is supposed to be shown when I click on a card. But, as mentioned before, I can’t understand why.
import React, { Component } from 'react';
import { Col, Card, CardTitle, Icon, Row, Container } from 'react-materialize';
class Details extends Component {
constructor(props) {
super(props);
}
renderItem(item) {
switch (item) {
case null:
return (<div></div>);
default:
return (
<Col m={6} s={12}>
<Card
actions={[
<a key={item.id} href='/'>Details</a>
]}
closeIcon={<Icon>close</Icon>}
header={<CardTitle image="https://materializecss.com/images/sample-1.jpg" />}
revealIcon={<Icon>more_vert</Icon>}
title={item.name}
>
</Card>
</Col>
);
}
}
renderDetails(item) {
switch(item) {
case null:
return (<div></div>);
default:
return (
<Col m={6} s={12}>
<p>{item.name}</p>
<p>{item.location}</p>
<p>{item.supplier}</p>
<p>{new Intl.DateTimeFormat('it-IT', { year: 'numeric', month: 'short', day: '2-digit', hour12: true, hour: 'numeric', minute: 'numeric', second: 'numeric' }).format(new Date(item.insertDate))}</p>
<p>{new Intl.DateTimeFormat('it-IT', { year: 'numeric', month: 'long', day: '2-digit' }).format(new Date(item.purchaseDate))}</p>
<p>{(item.inUse).toString()}</p>
<p>{item.invoiceNumber}</p>
</Col>
);
}
}
render() {
return(
<Container>
<Row>
{this.renderItem(this.props.item)}
{this.renderDetails(this.props.item)}
</Row>
</Container>
);
}
}
export default Details;
I know I put a lot of code, but if somebody could help me it would be really appreciated.