Я хочу сделать модальный компонент в реакции с компонентом класса, но похоже, что состояние не обновляется. Нужна помощь в направлении меня)

Проблема: 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);

Можете ли вы предоставить минимальный рабочий пример для codeandbox или эквивалентного?

P.E. Joëssel 14.12.2020 22:14

вот git, файловые страницы -> main.js спасибо, когда вы запускаете запуск npm, откроется главная страница, просто прокрутите вниз, вы увидите список элементов, где вы можете нажать кнопку «Быстрый поиск»

Eldar Tailov 14.12.2020 23:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
676
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы близки ! У меня работает, у меня нет тестового магазина

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

JB_DELR 15.12.2020 00:50

ДААААААААААААААААААААААА!!! Вы волшебник! это сработало, но я так и не понял, в чем проблема) видимо оператор && делает это лучше

Eldar Tailov 15.12.2020 04:48

Другие вопросы по теме