React-组件的生命周期

时间:2019-06-17 11:42:38

标签: reactjs

在这里的朋友的帮助下,像我这样的初学者反应 能够创建一个增量/减量组件。但是现在我需要在单击增量/减量按钮时更新对象。但是我第一次单击时得到的只是一个空对象(或数组)
这是我的增减部分:

import React from 'react';
import './ChooseQuantity.css';

const ChooseQuantity = ({ value, onChange, additionEnabled }) => {
    const shouldIncrement = additionEnabled;
    const shouldDecrement = value > 0;
    
    const decrement = () => {
        if (shouldDecrement) {
            onChange(value - 1);
        }
    }
    
    const increment = () => {
        if (shouldIncrement) {
            onChange(value + 1);
        }
    }

    const decrementButton = shouldDecrement ? (
        <button className="minus" onClick={decrement}>
            <i className="fas fa-minus"></i>
        </button>
    ) : <div className="space-button"></div>

    const incrementButton = shouldIncrement ? (
        <button className='plus' onClick={increment}>
            <i className="fas fa-plus"></i>
        </button>
    ) : <div className="space-button"></div>

    return (
        <div>
            {decrementButton}
                <span className="qtd">{value}</span>
            {incrementButton}
        </div>
    )
}

ChooseQuantity.defaultProps = {
    value: 0,
    additionEnabled: true,
}

export default ChooseQuantity

这是我的批次组件:

import React from 'react'
import ChooseQuantity from '../../components/ChooseQuantity/ChooseQuantity.js';

const Lot = ({
    lotUniqueNumber,
    ticketUniqueNumber,
    name,
    lotPrice,
    lotPriceTax,
    quantity,
    onQuantityChange,
    additionEnabled,
    maxPurchase,
}) => {
    const onQuantityChangeInternal = newValue => {
        onQuantityChange(ticketUniqueNumber, lotUniqueNumber, lotPrice, lotPriceTax, newValue, maxPurchase)
    }
    return (
        <div className="row">
            <div className="col-8">
                <h5 className="lot-name">{name}</h5>
                <h6 className="lot-price">
                    R$ {lotPrice.replace('.', ',')} <br />
                    <small>(R$ {lotPrice.replace('.', ',')} + R$ {lotPriceTax.replace('.', ',')})</small>
                </h6>
            </div>
            <div className="col-4">
                <ChooseQuantity
                    value={quantity}
                    onChange={onQuantityChangeInternal}
                    additionEnabled={additionEnabled}
                    maxPurchase={maxPurchase}
                    lotPrice={lotPrice}
                    lotPriceTax={lotPriceTax}
                />
            </div>
        </div>
    )
}

export default Lot

这是我的事件组件,在其中我呈现了按钮增减:

import React, { Component } from 'react';
import api from '../../components/Util/api.js';//para requisições
import Header from '../../components/Header/Header';
import Lot from './Lot'

import './Event.css';
import '../../components/Css/App.css';

const separator = '/';
class Event extends Component {
    constructor(props) {
        super(props);
        this.state = {
            event: {},
            dates: [],
            tickets: [],
            choose_quantity: 0,
            qtd: 0,
            newQtd: 0,
            teste: [],
            showAddButton: true,
            showRemoveButton: true,
            selectedQuantities: {},
            maxTotalItems: 0,
            total: {
                price: 0,
                quantity: 0,
            },
        }
    }

    async componentDidMount() {
        const { id } = this.props.match.params;
        await api.get(`event/${id}`)
            .then(res => {
                const event = res.data.data;
                this.setState({ event });
                this.setState({ dates: event.dates })

                this.state.dates.map((date, i) =>
                    this.setState({ tickets: this.state.dates[i].tickets })
                )

                this.state.tickets.map((ticket, i) =>
                    this.setState({ lots: ticket.lot })
                )
                this.setState({
                    selectedQuantities: {},
                })
                this.setState({ maxTotalItems: this.state.event.max_purchase });
                console.log(this.state.tickets);
            })
    }

    onQuantityChange = (ticketUniqueNumber, lotUniqueNumber, lotPrice, lotPriceTax, newValue) => {
        this.setState(prevState => {
            this.setState({
                // selectedQuantities: { ...prevState.selectedQuantities, [this.getSelectedStateKey(ticketUniqueNumber, lotUniqueNumber)]: newValue, },
                selectedQuantities: { ...prevState.selectedQuantities, [`${ticketUniqueNumber}${separator}${lotUniqueNumber}`]: newValue, },
            })
        })
        console.log(this.state.selectedQuantities);
    }

    // getSelectedStateKey = (ticketUniqueNumber, lotUniqueNumber) =>
    //     `${ticketUniqueNumber}${separator}${lotUniqueNumber}`

    // getSelectedQuantity = (ticketUniqueNumber, lotUniqueNumber) =>
    //     this.state.selectedQuantities[
    //         this.getSelectedStateKey(ticketUniqueNumber, lotUniqueNumber)
    //     ]

    getSelectedQuantity = (ticketUniqueNumber, lotUniqueNumber) => this.state.selectedQuantities[`${ticketUniqueNumber}${separator}${lotUniqueNumber}`];

    getAdditionEnabled = () => Object.values(this.state.selectedQuantities).reduce((acc, i) => acc + i, 0) < this.state.maxTotalItems;

    onCheckoutButtonClick = () => {
        const selectedArray = Object.entries(this.state.selectedQuantities).map(
            ([key, quantity]) => {
                const [ticketUniqueNumber, lotUniqueNumber] = key.split(separator)
                return {
                    ticketUniqueNumber,
                    lotUniqueNumber,
                    quantity,
                }
            },
        )
        console.log(selectedArray);
    }

    render() {
        return (
            <div>
                <Header Title={this.state.event.name} ToPage="/" />
                <div className="container-fluid padding-15 event">
                    <div className="mt-5">
                        <img className="card-img-top" src={this.state.event.banner_app} alt={this.state.event.name} />
                        <div className="row no-margin mb-3">
                            <div className="col-8 no-padding">
                                <h1 className="event-title">{this.state.event.name}</h1>
                                <h1 className="event-place">
                                    <i className="fas fa-pin"></i>
                                    {this.state.event.place}
                                </h1>
                            </div>
                            <div className="col-4 event-date-col align-items">
                                <span className="event-date" id="event-date">
                                </span>
                                {this.state.dates.map((date, i) =>
                                    <span className="event-date" key={i}>
                                        {date.date}
                                    </span>
                                )}
                            </div>
                        </div>

                        {
                            this.state.tickets.map((ticket, i) =>
                                (
                                    <div key={i}>
                                        <div className="row">
                                            <div className="col">
                                                <h3 className="ticket-name">{ticket.name}</h3>
                                            </div>
                                        </div>
                                        {ticket.lot.map((lot, l) =>
                                            <Lot
                                                key={l}
                                                lotUniqueNumber={lot.unique_number}
                                                ticketUniqueNumber={ticket.unique_number}
                                                lotName={lot.name}
                                                lotPrice={lot.price}
                                                lotPriceTax={lot.price_tax}
                                                onQuantityChange={this.onQuantityChange}
                                                maxPurchase={this.state.event.max_purchase}
                                                quantity={this.getSelectedQuantity(ticket.unique_number, lot.unique_number)}
                                                additionEnabled={this.getAdditionEnabled()}
                                            />
                                        )}
                                        <hr />
                                    </div>
                                )
                            )
                        }

                        <div className="row mt-5">
                            <div className="col">
                                <h6 className="text-default">Descrição</h6>
                            </div>
                        </div>
                        <div className="row">
                            <div className="col" dangerouslySetInnerHTML={{ __html: this.state.event.description }}></div>
                        </div>
                    </div>
                </div>
                <div className="row cart-footer">
                    <div className="col col-price">
                        <h6>{this.state.qtd} INGRESSOS</h6>
                        <h5>R$ 16,00</h5>
                    </div>
                    <button className="col col-purchase" onClick={this.onCheckoutButtonClick}>
                        Comprar
                    </button>
                </div>
            </div>
        )
    }
}

export default Event;

在控制台中出现错误:
警告:已从更新函数内部安排了更新(setState,replaceState或forceUpdate)。更新函数应该是纯函数,且副作用为零。考虑在第57行(onQuantityChange函数)中使用componentDidUpdate或回调。。当我单击onCheckoutButtonClick时,对象返回corretamente。有什么可以帮助我的吗?

2 个答案:

答案 0 :(得分:0)

您不能在setState内使用setState

    onQuantityChange = (ticketUniqueNumber, lotUniqueNumber, lotPrice, lotPriceTax, newValue) => {
                this.setState(prevState => {
                        // selectedQuantities: { ...prevState.selectedQuantities, [this.getSelectedStateKey(ticketUniqueNumber, lotUniqueNumber)]: newValue, },
                        selectedQuantities: { ...prevState.selectedQuantities, [`${ticketUniqueNumber}${separator}${lotUniqueNumber}`]: newValue, },
                },() => console.log(this.state.selectedQuantities))
           }

答案 1 :(得分:0)

按钮的点击增量/减少

onQuantityChange = (ticketName, ticketPrevenda, ticketUniqueNumber, lotType, lotUniqueNumber, lotPrice, lotPriceTax, newValue) => {
        // console.log(ticketName);
        this.setState(prevState => {
            this.setState({
                selectedQuantities: { ...prevState.selectedQuantities, [`${ticketName}${separator}${ticketPrevenda}${separator}${ticketUniqueNumber}${separator}${lotType}${separator}${lotUniqueNumber}${separator}${lotPrice}${separator}${lotPriceTax}`]: newValue },
            })
        }, () => {
            // console.log(this.state.selectedQuantities);
            const selectedArray = Object.entries(this.state.selectedQuantities).map(
                ([key, quantity]) => {
                    const [ticketName, ticketPrevenda, ticketUniqueNumber, lotType, lotUniqueNumber, lotPrice, lotPriceTax] = key.split(separator)
                    const totalLotPrice = parseFloat(lotPrice + lotPriceTax);
                    const total = parseFloat(totalLotPrice * quantity);
                    return {
                        ticketName,
                        ticketPrevenda,
                        ticketUniqueNumber,
                        lotType,
                        lotUniqueNumber,
                        lotPrice,
                        lotPriceTax,
                        quantity,
                        totalLotPrice,
                        total
                    }
                },
            )
            // console.log(selectedArray);            

            //SOMANDO A QTD E ATUALIZANDO O STATE
            var lotQuantity = selectedArray.reduce(function(prevVal, elem) {
                const lotQuantity = prevVal + elem.quantity;
                return lotQuantity;
            }, 0);
            this.setState({ qtd: lotQuantity });
            
            //SOMANDO O TOTAL E ATUIALIZANDO O STATE
            var total = selectedArray.reduce(function(prevVal, elem) {
                const total = prevVal + elem.total;
                return total;
            }, 0);
            this.setState({priceTotal: total})            

            //MOSTRAR/OCULTAR FOOTER
            if (lotQuantity > 0) {
                this.setState({ totalZero: true });
            } else {
                this.setState({ totalZero: false });
            }

            //OBJETO CART
            var lot = selectedArray;
            var tickets = {
                name: ticketName,
                prevenda: ticketPrevenda,
                unique_number: ticketUniqueNumber,
                lot: lot
            }

            var total = {
                price: total,
                quantity: lotQuantity,
            };

            var events = {
                banner_app: this.state.event.banner_app,
                installments: this.state.event.installments,
                max_purchase: this.state.event.max_purchase,
                name: this.state.event.name,
                tickets: tickets,
                unique_number: this.state.event.unique_number,
                total_tickets: lotQuantity
            };
            var cart = { events: events, total: total };
            localStorage.setItem('cart', JSON.stringify(cart));
            localStorage.setItem('qtd', JSON.stringify(lotQuantity));
            // console.log(lotQuantity);
            console.log(JSON.parse(localStorage.getItem('qtd')));
            
            // console.log(JSON.parse(localStorage.getItem('cart')));
            //OBJETO CART
        })
    }

创建的对象

enter image description here