如何创建订单汇总组件

问题描述

我想在右侧创建一个订单汇总组件,如下所示:How the UI looks

但是,我不知道该怎么做,因为我对 MERN 堆栈还很陌生。这是餐厅详细信息显示方式的组件:

import React,{ useState,useEffect } from "react";
import { usedispatch,useSelector } from "react-redux";
import { Grid,CircularProgress } from "@material-ui/core";
import useStyles from "./styles";
import { useParams } from "react-router-dom";
import { restaurantDetails } from "../../actions/restaurants";
import { TextField,Button,Typography,Paper } from "@material-ui/core";
import { LinearProgress } from "@material-ui/core";

import { Container,Row,Col } from "react-bootstrap";
import "bootstrap/dist/css/bootstrap.css";
import OrderSummary from "./OrderSummary/OrderSummary";

const RestaurantDetails = (props) => {
  const classes = useStyles();

  const dispatch = usedispatch();
  let { _id } = useParams();

  const [restaurantInfo,setRestaurantInfo] = useState();

  useEffect(() => {
    try {
      dispatch(restaurantDetails(_id)).then((res) => setRestaurantInfo(res));
      console.log("this is restaurantInfo" + restaurantInfo);
      console.log(_id);
    } catch (e) {
      console.error(e);
    }
  },[dispatch]);

  return !restaurantInfo ? (
    <CircularProgress />
  ) : (
    <Container>
      <LinearProgress variant="determinate" value="20" color="secondary" />;
      <Row>
        <Col sm={8}>
          {" "}
          <div className={classes.root}>
            <Grid container spacing={3}>
              <Grid item xs={12}>
                <Paper className={classes.paper}>{restaurantInfo.name} </Paper>
              </Grid>
              <Grid item xs={12} sm={6}>
                <Paper className={classes.paper}>{restaurantInfo.categoryname1}</Paper>
              </Grid>
              <Grid item xs={12} sm={6}>
                <Paper className={classes.paper}>{restaurantInfo.categoryname2}</Paper>
              </Grid>
              <Grid item xs={6} sm={3}>
                <div className="">
                  <img alt="" className="" src="images/3981417.jpg" />
                  <div className="">
                    <div className="">
                      <h3 className="">{restaurantInfo.itemName11}</h3>
                      <p className="">description here</p>
                      <h6 className="">£{restaurantInfo.itemPrice11}</h6>
                      <Button variant="contained" color="secondary">
                        Add To Order
                      </Button>
                    </div>
                  </div>
                </div>
              </Grid>
              <Grid item xs={6} sm={3}>
                <div className="">
                  <img alt="" className="" src="images/3981417.jpg" />
                  <div className="">
                    <div className="">
                      <h3 className="">{restaurantInfo.itemName12}</h3>
                      <p className="">description here</p>
                      <h6 className="">£{restaurantInfo.itemPrice12}</h6>
                      <Button variant="contained" color="secondary">
                        Add To Order
                      </Button>
                    </div>
                  </div>
                </div>
              </Grid>
              <Grid item xs={6} sm={3}>
                <div className="">
                  <img alt="" className="" src="images/3981417.jpg" />
                  <div className="">
                    <div className="">
                      <h3 className="">{restaurantInfo.itemName21}</h3>
                      <p className="">description here</p>
                      <h6 className="">£{restaurantInfo.itemPrice21}</h6>
                      <Button variant="contained" color="secondary">
                        Add To Order
                      </Button>
                    </div>
                  </div>
                </div>
              </Grid>
              <Grid item xs={6} sm={3}>
                <div className="">
                  <img alt="" className="" src="images/3981417.jpg" />
                  <div className="">
                    <div className="">
                      <h3 className="">{restaurantInfo.itemName22}</h3>
                      <p className="">description here</p>
                      <h6 className="">£{restaurantInfo.itemPrice22}</h6>
                      <Button variant="contained" color="secondary">
                        Add To Order
                      </Button>
                    </div>
                  </div>
                </div>
              </Grid>
            </Grid>
          </div>
        </Col>
        <OrderSummary />
      </Row>
    </Container>
    // <div>
    //   <h2>Restaurant id is: {_id}</h2>
    //   <h2>Restaurant name is: {restaurantInfo.name}</h2>
    // </div>
  );
};

export default RestaurantDetails;

这是目前的订单汇总组件。显然,我想在添加显示商品名称和价格以便结帐

import React,CircularProgress } from "@material-ui/core";
import useStyles from "./styles";
import { Row,Col } from "react-bootstrap";
import { TextField,Paper } from "@material-ui/core";

import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import CardHeader from "@material-ui/core/CardHeader";
import CardActions from "@material-ui/core/CardActions";
import { Divider } from "@material-ui/core";

import "bootstrap/dist/css/bootstrap.css";
const OrderTotal = () => {
  const classes = useStyles();

  return (
    <div>
      <Col sm={4}>
        {" "}
        <Card className={classes.root}>
          <CardHeader title="Order Summary" className={classes.header} />
          <Divider variant="middle" />
          <CardContent>
            <div className={classes.list}>
              <Row>
                <Col sm={6}>
                  <Typography align="center">display Item</Typography>
                </Col>
                <Col sm={6}>
                  <Typography align="center">display Prices</Typography>
                </Col>
              </Row>
            </div>
          </CardContent>
          <Divider variant="middle" />
          <CardActions className={classes.action}>
            <Button variant="contained" color="primary" className={classes.button}>
              Order Now
            </Button>
          </CardActions>
        </Card>
      </Col>
    </div>
  );
};

export default OrderTotal;

我该如何实现?我如何将价格和名称传递给订单汇总组件并在添加删除它们时列出它们?我真的很感激,因为我似乎无法解决这个问题!

解决方法

您需要将当前购物车项目存储在 redux 状态。您将需要一个将商品添加到购物车的操作。您的减速器需要处理此操作并更新购物车数据。这是一个非常基本的实现:

const orderSlice = createSlice({
  name: 'order',initialState: {
    items: [],status: 'unsubmitted'
  },reducers: {
    addToOrder: (state,action) => {
      state.items.push(action.payload);
    },submitOrder: (state) => {
      state.status = 'pending';
    }
  }
})

export const orderReducer = orderSlice.reducer;

export const {addToOrder,submitOrder} = orderSlice.actions;

您的“添加到订单”Button 需要一个 onClick 处理程序来调度您的操作。

<Button
  variant="contained"
  color="secondary"
  onClick={() => dispatch(addToOrder({
    name: restaurantInfo.itemName12,price: restaurantInfo.itemPrice12
  }))}
>
  Add To Order
</Button>

您的 OrderTotal 组件将使用 useSelector 钩子从 redux 访问购物车数据。

const orderItems = useSelector(state => state.order.items);
const orderTotal = orderItems.reduce((total,item) => total + item.price,0);

作为旁注,您可能不应该将 restaurantInfo 存储在您的组件状态中,因为它似乎已经在 redux 中设置了。相反,您应该使用 useSelector 访问它。