React Project:Step3 Add Order Button & Order model

本文档详细介绍了如何在React项目中逐步添加订单按钮及订单模型。首先在buildcontrols组件中添加order按钮,并根据BuildBurger组件的purchasable状态控制按钮可用性。接着创建order组件,用于展示订单详情,通过modal.js的state控制其显示和隐藏。OrderSummary.js组件显示订单内容,包括burger的ingredients和prices。进一步完善了order model。同时,实现了backdrop.js,作为订单页面的背景控制,点击backdrop可关闭订单模型。最后,在OrderSummary界面添加button组件,用于交互操作,并确保Burgerbuilder组件能正确传递函数给子组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为buildcontrols添加order按钮

在这里插入图片描述
显示在按钮下方;
并根据BuildBurger传入的purchasable props,控制该button的有效性;

import React from 'react';
import classes from './BuildControls.module.css';
import BuildControl from './BuildControl/BuildControl';


const controls=[
  {label:'Salad',type:'salad'},
  {label:'Bacon',type:'bacon'},
  {label:'Cheese',type:'cheese'},
  {label:'Meat',type:'meat'}
];

const buildControls =(props)=>(
  <div className={classes.BuildControls}>
    <p>Current Price: <strong>{props.price.toFixed(2)}</strong></p>
    {controls.map((control)=>(
      <BuildControl 
        key = {control.label} 
        label={control.label}
        added={()=>props.ingredientAdded(control.type)}
        removed={()=>props.ingredientRmoved(control.type)}
        disabled={props.disabled[control.type]}
        />
    ))}
    <button 
        className={classes.OrderButton}
        disabled={!props.purchasable}
        onClick={props.ordered}
        >ORDER NOW</button>
  </div>
);

export default buildControls;

添加order component——按下order按钮后显示的页面

BuildBurger控制显示的位置+state控制是否显示

import React,{Component} from 'react';
import Aux from '../../hoc/Auxiliary';
import Burger from '../../components/Burger/Burger';
import BuildControls from '../../components/Burger/BuildControls/BuildControls';
import Modal from '../../components/UI/Modal/Modal';
import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary';
const INGREDIENT_PRICES={
  salad:20,
  cheese:14,
  meat:99,
  bacon:17
};

class BurgerBuilder extends Component{
  state ={
    ingredients:{
      salad:0,
      bacon:0,
      cheese:0,
      meat:0
    },
    totalPrice:11,
    purchasable:false,
    purchasing:false
  }

  updatePurchaseState(getst){  //state为异步,所以在add和remove中调用此函数,此函数中得到的state不一定为set后的state,故需要传入getst——即add和remove后的state
    const ingredients={...getst};
    const sum = Object.keys(ingredients)
                .map(igKey=>{
                  return ingredients[igKey]
                })
                .reduce((sum,el)=>sum+el,0);
    this.setState({purchasable:sum>0});
  }

  addIngredientHandler = (type)=>{
    const getst={...this.state.ingredients};
    getst[type]+=1;
    let getprice = this.state.totalPrice;
    getprice+=INGREDIENT_PRICES[type];
    this.setState({
      ingredients:getst,
      totalPrice:getprice
    });
    this.updatePurchaseState(getst);
  }

  removeIngredientHandler =(type)=>{
    const getst={...this.state.ingredients};
    getst[type]-=1;
    let getprice = this.state.totalPrice;
    getprice-=INGREDIENT_PRICES[type];
    this.setState({
      ingredients:getst,
      totalPrice:getprice
    });
    this.updatePurchaseState(getst);
  }

  purchaseHandler=()=>{                  //若不用arrow则this会报错
    this.setState({purchasing:true});
  }

  render(){
    const disabledInfo = {
      ...this.state.ingredients
    };
    for(let key in disabledInfo){
      disabledInfo[key] = disabledInfo[key]<=0; //返回true false
    }
    return(
      <Aux>
        <Modal show={this.state.purchasing}>
          <OrderSummary ingredients={this.state.ingredients}/>
        </Modal>
        <Burger ingredients={this.state.ingredients}/>
        <BuildControls 
          ingredientAdded={this.addIngredientHandler}
          ingredientRmoved={this.removeIngredientHandler}
          disabled={disabledInfo}
          price={this.state.totalPrice}
          purchasable={this.state.purchasable}
          ordered={this.purchaseHandler}
        />
      </Aux>
    );
  }
}

export default BurgerBuilder;

modal.js得到state属性,控制order页面的显示与否

import React from 'react';
import classes from './Modal.module.css';


const modal = (props)=>(
    <div 
      className={classes.Modal}
      style={{
        transform:props.show? 'translateY(0)':'translateY(-100vh)',
        opacity:props.show?'1':'0'
      }}
      >
      {props.children}
    </div>
);

export default modal;

OrderSummary.js为该页面的内容

包括显示的逻辑——即ul包li;
使用keys+maps对ingredients进行分离;

import React from 'react';
import Aux from '../../../hoc/Auxiliary';


const orderSummary = (props)=>{
  const ingredientSummary = Object.keys(props.ingredients)
        .map((igKey)=>{
        return  (
        <li key={igKey}>
          <span style={{textTransform:'capitalize'}}>{igKey}</span> :{props.ingredients[igKey]}
        </li>)
        })


  return (
    <Aux>
      <h3>Your order</h3>
      <p>A delicious burger with the following ingredients:</p>
      <ul>
        {ingredientSummary}
      </ul>
      <p>Continue to Checkout?</p>
    </Aux>
  );
};

export default orderSummary;

通过buildburger的state传入的内容,可以显示burger的ingredients和prices;


完善order model

  1. 添加backdrop
  2. 添加button

backdrop.js——在model显示时显示控制背景

对backdrop添加onclick事件——点击后返回,从burgerbuilder->Model->backdrop一路下传;

import React from 'react';
import classes from './Backdrop.module.css';

const backdrop = (props)=>(
  props.show? <div 
                className={classes.Backdrop}
                onClick={props.clicked}
                ></div>: null
);

export default backdrop;

backdrop放在model.js中
model包裹着order界面——backdrop在order外;

import React from 'react';
import classes from './Modal.module.css';
import Aux from '../../../hoc/Auxiliary';
import Backdrop from '../Backdrop/Backdrop';

const modal = (props)=>(
    <Aux>
      <Backdrop 
        show ={props.show}
        clicked={props.closemodal}
        />
      <div 
        className={classes.Modal}
        style={{
          transform:props.show? 'translateY(0)':'translateY(-100vh)',
          opacity:props.show?'1':'0'
        }}
        >
        {props.children}
      </div>
    </Aux>
);

export default modal;

添加button——orderSummary界面

首先添加一个button文件夹,存放button component,方便控制style;
Button.js

import React from 'react';
import classes from './Button.module.css';

const button =(props)=>(
  <button
    className={[classes.Button,classes[props.btnType]].join(' ')}
    onClick={props.clicked}
    >{props.children}</button>
);

export default button;

在ordersummary中引入button;
设置class和onclick事件;
从burgerbuilder->Ordersummary;

import React from 'react';
import Aux from '../../../hoc/Auxiliary';
import Button from '../../UI/Button/Button';

const orderSummary = (props)=>{
  const ingredientSummary = Object.keys(props.ingredients)
        .map((igKey)=>{
        return  (
        <li key={igKey}>
          <span style={{textTransform:'capitalize'}}>{igKey}</span> :{props.ingredients[igKey]}
        </li>)
        })


  return (
    <Aux>
      <h3>Your order</h3>
      <p>A delicious burger with the following ingredients:</p>
      <ul>
        {ingredientSummary}
      </ul>
      <p>Continue to Checkout?</p>
      <Button btnType="Danger" clicked={props.purchaseCanceled}>CANCEL</Button>
      <Button btnType="Success" clicked={props.purchaseContinued}>CONTINE</Button>
    </Aux>
  );
};

export default orderSummary;

Burgerbuilder传入的函数

import React,{Component} from 'react';
import Aux from '../../hoc/Auxiliary';
import Burger from '../../components/Burger/Burger';
import BuildControls from '../../components/Burger/BuildControls/BuildControls';
import Modal from '../../components/UI/Modal/Modal';
import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary';
const INGREDIENT_PRICES={
  salad:20,
  cheese:14,
  meat:99,
  bacon:17
};

class BurgerBuilder extends Component{
  state ={
    ingredients:{
      salad:0,
      bacon:0,
      cheese:0,
      meat:0
    },
    totalPrice:11,
    purchasable:false,
    purchasing:false
  }

  updatePurchaseState(getst){  //state为异步,所以在add和remove中调用此函数,此函数中得到的state不一定为set后的state,故需要传入getst——即add和remove后的state
    const ingredients={...getst};
    const sum = Object.keys(ingredients)
                .map(igKey=>{
                  return ingredients[igKey]
                })
                .reduce((sum,el)=>sum+el,0);
    this.setState({purchasable:sum>0});
  }

  addIngredientHandler = (type)=>{
    const getst={...this.state.ingredients};
    getst[type]+=1;
    let getprice = this.state.totalPrice;
    getprice+=INGREDIENT_PRICES[type];
    this.setState({
      ingredients:getst,
      totalPrice:getprice
    });
    this.updatePurchaseState(getst);
  }

  removeIngredientHandler =(type)=>{
    const getst={...this.state.ingredients};
    getst[type]-=1;
    let getprice = this.state.totalPrice;
    getprice-=INGREDIENT_PRICES[type];
    this.setState({
      ingredients:getst,
      totalPrice:getprice
    });
    this.updatePurchaseState(getst);
  }

  purchaseHandler=()=>{                  //若不用arrow则this会报错
    this.setState({purchasing:true});
  }

  purchaseCancelHandler=()=>{
    this.setState({purchasing:false});
  }

  purchaseContinueHandler=()=>{
    alert('You continue!');
  }

  render(){
    const disabledInfo = {
      ...this.state.ingredients
    };
    for(let key in disabledInfo){
      disabledInfo[key] = disabledInfo[key]<=0; //返回true false
    }
    return(
      <Aux>
        <Modal 
          show={this.state.purchasing}
          closemodal={this.purchaseCancelHandler}
          >
          <OrderSummary 
            ingredients={this.state.ingredients}
            purchaseCanceled={this.purchaseCancelHandler}
            purchaseContinued={this.purchaseContinueHandler}
            />
        </Modal>
        <Burger ingredients={this.state.ingredients}/>
        <BuildControls 
          ingredientAdded={this.addIngredientHandler}
          ingredientRmoved={this.removeIngredientHandler}
          disabled={disabledInfo}
          price={this.state.totalPrice}
          purchasable={this.state.purchasable}
          ordered={this.purchaseHandler}
        />
      </Aux>
    );
  }
}

export default BurgerBuilder;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值