为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
- 添加backdrop
- 添加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;