我想做模态组件与类组件反应,但似乎状态没有更新。需要指导我的帮助)

问题描述 投票:0回答:1

问题:商店从数据库获取项目,主组件用简短信息呈现这些项目。单击后,我想打开模态组件,其中包含有关该产品的详细信息。 我的想法 -> 创建变量,在其中存储有关

selectedItem
的信息 -> 创建允许出现模态组件的变量。也就是说,它首先将信息写入
selectedItem
并使用 props 将此变量传递给模态组件,然后我们发出命令以使用
openModal
渲染该组件。但我遇到的问题是
openModalAction
setState 似乎不起作用。它根本不会改变状态。我记得 setState 是异步的,但是在 this.setState 中写入 this.setState 没有帮助,而且看起来很奇怪。无论如何,主要问题是它说通过 props 获得的 Item 是未定义的......

我应该尝试使用功能组件来实现它吗?它会产生任何差异吗?我的逻辑适合做模态窗口吗?你会怎么做?

我有一个非常简单的任务接缝,就像我在 Vue 上做过很多次一样,没有任何问题,但 React 每天都让我发疯。但说实话,我开始喜欢 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; // getting 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);
javascript reactjs react-props
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; // getting 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);
© www.soinside.com 2019 - 2024. All rights reserved.