Problem: Store gets items from DB, and main component renders those Items with short info. On click I want to open modal component with detailed info about this product.
My idea -> create variable where I would store info about selectedItem
-> create variable which allows to appear modal component. And that is it first it writes info into selectedItem
and with props it passes this variable to modal component and we give command to render this component with openModal
. But where I have a problem is in openModalAction
setState doesn't seem to be working. It simply doesn't change the state. I remember that setState is asynchronous, but writting this.setState inside this.setState didn't help and it looked weird. Anyhow main issue it says Item which it gets by props is undefined...
Should I try do it with functional component and will it make any differences? Is my logic right for doing modal windows and how would you do it ?
I have a pretty easy task seams like which I've done on Vue many times with no issues, but React drives me crazy every single day. But to be honest I starting like react, with his help I understand Vue even better, let's say React shows me how Vue works under the hood.
import React from 'react'
import { withStyles } from '@material-ui/styles';
import { Typography } from '@material-ui/core'
import Button from '@material-ui/core/Button';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Grid from '@material-ui/core/Grid'
import {inject, observer} from 'mobx-react'
import ItemModal from '@components/main/modalItem'
const useStyles = {
media:{
height: "145px"
},
modal: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}
}
let Main = inject("store")(observer(class Main extends React.Component {
constructor(props){
super(props);
this.state = {
selectedItem: {},
openModal: false
}
}
openModalAction = (el) => {
this.setState({
selectedItem: el,
openModal: true
})
}
closeModalAction = () => {
this.setState({
selectedItem: {},
openModal: false
})
}
modalComponent = () => {
if(this.state.openModal)
return (<ItemModal item = {this.selectedItem} />)
}
render(){
const { classes } = this.props;
let productModel = this.props.store.products; // gettting products instance from Mobx Store
let productsDom = productModel.getAll.map((el, i) => { // making DOM
return (
<Grid item xs={3} key={i}>
<Card>
<CardContent>
<Typography variant="h4">{el.title}</Typography>
<Typography variant="subtitle1">{el.price}</Typography>
</CardContent>
<CardActions>
<Button color="secondary" onClick={ () => this.openModalAction(el) }>Quick look</Button>
<Button color="primary">Add to cart</Button>
</CardActions>
</Card>
</Grid>)
})
return (
<React.Fragment>
{/*Modal item*/}
{ this.modalComponent() }
{/*Items for sale*/}
<div>
<Typography variant="h3" align="center" gutterBottom> Items </Typography>
<Grid container spacing={3}>
{ productsDom }
</Grid>
</div>
</div>
</React.Fragment>
)
}
}))
export default withStyles(useStyles)(Main);
HERE IS MODAL COMPONENT
import React from "react"
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import { Typography } from "@material-ui/core";
import {withStyles} from "@material-ui/styles";
import PropType from 'prop-types'
import Grid from '@material-ui/core/Grid'
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
class ModalItem extends React.Component{
render(){
const { classes } = this.props;
let item = this.props.item;
return(
<Card>
<CardContent>
<Grid container>
<Grid item xs={6}>
</Grid>
<Grid item xs={6}>
<Typography variant="h3">{item.title}</Typography>
<Typography variant="subtitle1">{item.price}</Typography>
<Grid container item xs={12}>
<Grid item xs={6}>
<TextField
type="number"/>
</Grid>
<Grid item xs={6}>
<Button color="primary">Add to cart</Button>
</Grid>
</Grid>
<Typography variant="subtitle2">Category</Typography>
<Button>Full review</Button>
</Grid>
</Grid>
</CardContent>
</Card>
)
}
}
ModalItem.propTypes = {
item: PropType.object
}
export default withStyles(useStyles)(ModalItem);