Проблема: Store получает элементы из БД, а основной компонент отображает эти элементы с краткой информацией. При нажатии я хочу открыть модальный компонент с подробной информацией об этом продукте.
Моя идея -> создать переменную, в которой я буду хранить информацию о selectedItem -> создать переменную, которая позволяет отображать модальный компонент. И все, сначала он записывает информацию в selectedItem и с помощью реквизита передает эту переменную модальному компоненту, а мы даем команду отрисовать этот компонент с помощью openModal. Но проблема в том, что openModalAction setState, похоже, не работает. Это просто не меняет состояние. Я помню, что setState асинхронный, но запись this.setState внутри this.setState не помогла и выглядела странно. Во всяком случае, основная проблема, в которой он говорит, что элемент, который он получает с помощью реквизита, не определен...
Должен ли я попробовать сделать это с функциональным компонентом, и будет ли это иметь какое-либо значение? Правильна ли моя логика для создания модальных окон и как бы вы это сделали?
У меня есть довольно простые задачи, подобные тем, что я делал на Vue много раз без проблем, но React сводит меня с ума каждый божий день. Но, если честно, мне начинает нравиться реагировать, с его помощью я понимаю Vue еще лучше, допустим, React показывает мне, как Vue работает под капотом.
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);
ЗДЕСЬ МОДАЛЬНЫЙ КОМПОНЕНТ
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);
вот git, файловые страницы -> main.js спасибо, когда вы запускаете запуск npm, откроется главная страница, просто прокрутите вниз, вы увидите список элементов, где вы можете нажать кнопку «Быстрый поиск»



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы близки ! У меня работает, у меня нет тестового магазина
const useStyles = {
media:{
height: "145px"
},
modal: { // remove modal from here to put in the right file ->ModalItem
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
})
}
render(){
const { classes } = this.props;
let productModel = this.props.store.products; // gettting products instance from Mobx Store
})
return (
<React.Fragment>
{/*Modal item*/}
{ this.state.openModal && // use && operator
<ModalItem item = {this.state.selectedItem} /> // change to ModalItem, remove space and add .state
}
{/*Items for sale*/}
<div>
<Typography variant = "h3" align = "center" gutterBottom> Items </Typography>
<Grid container spacing = {3}>
{productModel.getAll().map((el, i) => ( //maybe getAll()
<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>
))}
</Grid>
</div>
/*</div>*/ //remove this
</React.Fragment>
)
}
}))
Модальный элемент:
const useStyles = {
modal: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}
}
class ModalItem extends React.Component{
render(){
const { classes } = this.props;
let item = this.props.item;
return(
<Card className = {classes.modal}>
<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);
Также обратите внимание на модальный интерфейс материала! material-ui.com/components/modal
ДААААААААААААААААААААААА!!! Вы волшебник! это сработало, но я так и не понял, в чем проблема) видимо оператор && делает это лучше
Можете ли вы предоставить минимальный рабочий пример для codeandbox или эквивалентного?