反应生命周期循环(React lifecycle loop)

编程入门 行业动态 更新时间:2024-10-17 23:27:29
反应生命周期循环(React lifecycle loop)

我有一个反应表单组件 - 它有一个方法,在已更新的表单上输入_handleInputChange并将更改添加到状态。 我正在尝试添加一个_calculatePrice ,顾名思义,它计算预订价格。 我试图让它显示给用户,这样当输入字段发生变化时,价格变化就会反映出来。

我正在努力弄清楚如何正确执行 - 我想这是缺乏对生命周期反应的知识,我已经阅读了文档并在堆栈上搜索了几个问题,但是,答案似乎在逃避我。 随着_calculatePrice方法更新一个状态值,然后再次调用自己,包含的示例会卡在循环中。

任何帮助将非常感激。

谢谢

Form.jsx

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;

I've got a react form component - it's got a method that _handleInputChange on the updated form input and adds the change to state. I'm trying to add a _calculatePrice, which as the name suggests, calculates the booking price. I'm trying to get it to display to the user so that when the input field alters, the price change is reflected.

I'm struggling to figure out how to execute this correctly - I imagine it's a lack of knowledge of react lifecycles, I have read the docs and search for a few questions on stack, however, the answer seems to be evading me. The example included gets stuck in a loop as the _calculatePrice method updates a state value which then calls itself again.

Any help would be much appreciated.

Thanks

Form.jsx

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;

最满意答案

尽量不要在您的州中包含重复信息。

例如,如果您的状态包含firstName和lastName ,则不需要fullName另一个状态。

尝试从你的状态中删除subTotal和total 。 相反,请在render方法内计算它。 这样,您可以避免导致setState调用的无限循环。

我创建了这个CodeSandbox ,它显示了一个简单的例子。

Try not to include duplicate information in your state.

For example, if your state contained firstName and lastName, you wouldn't need another state for fullName.

Try removing subTotal and total from your state. Instead, calculate it inside of your render method. This way, you avoid causing an infinite loop with your setState calls.

I created this CodeSandbox that shows a simple example of this.

更多推荐

本文发布于:2023-08-02 08:40:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1372350.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:生命周期   React   loop   lifecycle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!