Javascript 反应生命周期循环
我有一个react表单组件,它有一个方法,可以处理更新表单输入上的输入更改,并将更改添加到状态。我试图添加一个计算价格,顾名思义,它计算预订价格。我试图让它显示给用户,这样当输入字段改变时,价格的变化就会反映出来 我正在努力弄清楚如何正确地执行这一点——我想这是因为缺乏对react生命周期的了解,我已经阅读了文档并在stack上搜索了一些问题,然而,答案似乎在回避我。当_calculatePrice方法更新状态值,然后再次调用自身时,所包含的示例陷入循环中 任何帮助都将不胜感激 谢谢 Form.jsxJavascript 反应生命周期循环,javascript,reactjs,Javascript,Reactjs,我有一个react表单组件,它有一个方法,可以处理更新表单输入上的输入更改,并将更改添加到状态。我试图添加一个计算价格,顾名思义,它计算预订价格。我试图让它显示给用户,这样当输入字段改变时,价格的变化就会反映出来 我正在努力弄清楚如何正确地执行这一点——我想这是因为缺乏对react生命周期的了解,我已经阅读了文档并在stack上搜索了一些问题,然而,答案似乎在回避我。当_calculatePrice方法更新状态值,然后再次调用自身时,所包含的示例陷入循环中 任何帮助都将不胜感激 谢谢 Form.
尽量不要在您所在的州包含重复的信息 例如,如果您的状态包含firstName和lastName,则fullName不需要另一个状态 尝试从您的状态中删除小计和总计。相反,请在渲染方法中计算它。这样,就避免了setState调用导致无限循环
我创建了一个简单的例子。什么时候是将总计和小计添加到状态的合适时间?我需要在某个时候将其添加到数据库中?顺便说一句,谢谢你的回答——我已经把它标记为正确。一般来说,你永远不需要把总数和小计加到州里。对于将其发送到数据库的实例,可以重用计算总计和小计所需的函数。我更新了示例,向您展示了如何实现这一点。
import React, { Component } from 'react';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
class AddBooking extends Component {
constructor(props) {
super(props);
this.state = {
pitch: this.props.pitch,
firstName: null,
lastName: null,
email: null,
arrivalDate: this.props.dayQuery,
departureDate: this.props.dayQuery,
noDays: 1,
pitchType: "Standard",
adults: 0,
children: 0,
infants: 0,
hookUp: 0,
dogs: 0,
extraInfo: null,
price: 0,
deposit: 0,
paid: 0,
subTotal: 0,
total: 0,
}
this._handleDisplay = this._handleDisplay.bind(this);
this._getRefs = this._getRefs.bind(this);
this._handleInputChange = this._handleInputChange.bind(this);
this._calculatePrice = this._calculatePrice.bind(this);
}
componentDidUpdate() {
this._calculatePrice(this.state);
}
_getRefs(e) {
var tempBooking = {
pitch: parseInt(this.state.pitch),
firstName: this.state.firstName,
lastName: this.state.lastName,
email: this.state.email,
arrivalDate: this.state.arrivalDate,
departureDate: this.state.departureDate,
pitchType: this.state.pitchType,
adults: parseInt(this.state.adults),
children: this.state.children,
infants: this.state.infants,
hookUp: this.state.hookUp,
dogs: this.state.dogs,
extraInfo: this.state.extraInfo,
price: this.state.price,
deposit: this.state.deposit,
paid: this.state.paid
}
this.props.addBooking(tempBooking);
e.preventDefault();
this._handleDisplay();
}
_calculatePrice(data) {
var price = this.props.bookingPrice.in_season;
var a = (data.adults * price.adults);
var c = (data.children * price.children);
var i = (data.infants * price.infants);
var h = (data.hookUp * price.hookUp);
var d = (data.dogs * price.dogs);
var days = data.noDays;
var subTotal = a + c + i + h + d;
var total = subTotal * days;
this.setState({
subTotal: subTotal,
total: total
});
}
_handleDisplay() {
this.props.addDisplay();
}
_handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
var partialState = {};
partialState[name] = value;
this.setState(partialState);
}
render(){
var price = this.props.bookingPrice.in_season;
return (
<Modal isOpen={this.props.formVisibility} toggle={this._handleDisplay}>
<ModalHeader toggle={this._handleDisplay}>Add Booking</ModalHeader>
<ModalBody>
<div className="modal-body">
<div className="row">
<div className="col-7">
<form id="add-booking-form">
<i className="fa fa-address-card float-left mr-2 mt-1" aria-hidden="true"></i>
<h5>Personal</h5>
<div className="form-group row mt-3">
<div className="form-label-group col-6">
<input onChange={this._handleInputChange} id="firstName" className="form-control" ref="firstName" name="firstName" type="text" placeholder="First Name"/>
<label htmlFor="firstName" className="mx-3">First Name</label>
</div>
<div className="form-label-group col-6">
<input onChange={this._handleInputChange} id="lastName" className="form-control" ref="lastName" name="lastName" type="text" placeholder="Last Name"/>
<label htmlFor="lastName" className="mx-3">Last Name</label>
</div>
</div>
<div className="form-label-group">
<input onChange={this._handleInputChange} id="email" className="form-control" ref="email" name="email" type="email" placeholder="Email Address"/>
<label htmlFor="email">Email Address</label>
</div>
<hr className="mb-4 mt-4"></hr>
<i className="fa fa-calendar float-left mr-2 mt-1" aria-hidden="true"></i>
<h5>Pitch</h5>
<div className="form-group row mt-3">
<div className="form-label-group col-6">
<input defaultValue={this.props.pitch} onChange={this._handleInputChange} id="pitch" className="form-control" ref="pitch" name="pitch" type="number" placeholder="Pitch"/>
<label htmlFor="pitch" className="mx-3">Pitch</label>
</div>
<div className="form-label-group col-6">
<input onChange={this._handleInputChange} id="pitchType" className="form-control" ref="pitchType" name="pitchType" type="text" placeholder="Pitch Type"/>
<label htmlFor="pitchType" className="mx-3">Pitch Type</label>
</div>
</div>
<div className="form-group row">
<div className="form-label-group col-6">
<input defaultValue={this.props.dayQuery} onChange={this._handleInputChange} id="arrivalDate" className="form-control" ref="arrivalDate" name="arrivalDate" type="date" placeholder="Arrival"/>
<label htmlFor="arrivalDate" className="mx-3">Arrival</label>
</div>
<div className="form-label-group col-6">
<input defaultValue={this.props.dayQuery} onChange={this._handleInputChange} id="departureDate" className="form-control" ref="departureDate" name="departureDate" type="date" placeholder="Departure"/>
<label htmlFor="departureDate" className="mx-3">Departure</label>
</div>
</div>
<hr className="mb-4"></hr>
<i className="fa fa-users float-left mr-2 mt-1" aria-hidden="true"></i>
<h5>Group Details</h5>
<div className="form-group row mt-3">
<div className="form-label-group col-4">
<input onChange={this._handleInputChange} id="adults" className="form-control" ref="adults" name="adults" type="number" placeholder="Adults"/>
<label htmlFor="adults" className="mx-3">Adults</label>
<small id="emailHelp" className="form-text text-muted">18+</small>
</div>
<div className="form-label-group col-4">
<input onChange={this._handleInputChange} id="children" className="form-control" ref="children" name="children" type="number" placeholder="Children"/>
<label htmlFor="children" className="mx-3">Children</label>
<small id="emailHelp" className="form-text text-muted">12-17</small>
</div>
<div className="form-label-group col-4">
<input onChange={this._handleInputChange} id="infants" className="form-control" ref="infants" name="infants" type="number" placeholder="Infants"/>
<label htmlFor="infants" className="mx-3">Infants</label>
<small id="emailHelp" className="form-text text-muted">4+</small>
</div>
</div>
<div className="form-group row mt-3">
<div className="form-label-group col-6">
<input onChange={this._handleInputChange} id="hookUp" className="form-control" ref="hookUp" name="hookUp" type="number" placeholder="Hook Up"/>
<label htmlFor="hookUp" className="mx-3">Hook Up</label>
</div>
<div className="form-label-group col-6">
<input onChange={this._handleInputChange} id="dogs" className="form-control" ref="dogs" name="dogs" type="number" placeholder="Dogs"/>
<label htmlFor="dogs" className="mx-3">Dogs</label>
</div>
</div>
<div className="form-group row mt-3">
<div className="form-group col-12">
<textarea className="form-control" id="exampleFormControlTextarea1" placeholder="Extra Info" rows="3"></textarea>
</div>
</div>
<div className="form-group row">
<label className="col-2 col-form-label">Price</label>
<div className="col-10">
<input onChange={this._handleInputChange} className="form-control" ref="price" name="price" type="number"/>
</div>
</div>
<div className="form-group row">
<label className="col-2 col-form-label">Deposit</label>
<div className="col-10">
<input onChange={this._handleInputChange} className="form-control" ref="deposit" name="deposit" type="number"/>
</div>
</div>
<div className="form-group row">
<label className="col-2 col-form-label">Paid</label>
<div className="col-10">
<input onChange={this._handleInputChange} className="form-control" ref="paid" name="paid" type="number"/>
</div>
</div>
</form>
</div>
<div className="col-5">
<i className="fa fa-calculator float-left mr-2 mt-1" aria-hidden="true"></i>
<h4>Booking Price</h4>
<small id="passwordHelpBlock" className="form-text text-muted">
Summer Tariff & Forest Pitch
</small>
<ul className="list-group list-group-flush mt-3">
<li className={"list-group-item d-flex justify-content-between align-items-center " + (this.state.adults ? 'show' : 'hidden')}>
Adults x{this.state.adults}
<span className="pull-right">£{price.adults * this.state.adults}</span>
</li>
<li className={"list-group-item d-flex justify-content-between align-items-center " + (this.state.children ? 'show' : 'hidden')}>
Children x3
<span className="pull-right">£{price.children * this.state.children}</span>
</li>
<li className={"list-group-item d-flex justify-content-between align-items-center " + (this.state.infants ? 'show' : 'hidden')}>
Infants x2
<span className="pull-right">£{price.infants * this.state.infants}</span>
</li>
<li className="list-group-item d-flex justify-content-between align-items-center">
Subtotal (cost per night)
<span className="pull-right">£0</span>
</li>
<li className="list-group-item d-flex justify-content-between align-items-center font-weight-bold">
Total
<span className="pull-right">£0</span>
</li>
</ul>
</div>
</div>
</div>
</ModalBody>
<ModalFooter>
<Button color="danger" data-dismiss="modal" onClick={this._handleDisplay}>Close</Button>
<Button color="success" onClick={this._getRefs}>Save</Button>
</ModalFooter>
</Modal>
)
}
}
export default AddBooking;