按条件显示/隐藏数组中的元素

时间:2019-06-12 14:02:22

标签: reactjs

我有一个呈现在数组中的组件。该组件仅显示2个按钮和一个输入文本。此按钮增加/减少1个项目(请参见图片)。我有一些来自API的数据,其中一项限制购买。我需要在上限较高时隐藏增量按钮,并在上限较低时显示。我可以做到,但是我的问题是只用一个按钮而不是数组中的所有按钮

//My Buttons increment/decrease component
import React, { Component } from 'react';
import api from '../../components/Util/api.js';//para requisições
import './ChooseQuantity.css';

var cart = {};
var total = {};
var events = {};
var tickets = [];
var quantity = [];
class ChooseQuantity extends Component {
    constructor(props) {
        super(props);
        this.state = {
            qtd: 0,
            showAddButton: true,
            showRemoveButton: true,
        }
    }
    addItem() {
        // quantity = [];
        localStorage.removeItem('quantity');

        this.setState({ showRemoveButton: false });
        this.setState({ qtd: this.state.qtd += 1 });
        quantity.push(parseInt(this.state.qtd));
        localStorage.setItem('quantity', quantity.length);

        console.log(this.state.showAddButton);
        
        // if (tickets.indexOf(this.props.tickets)) {
        //     tickets.push(this.props.tickets);
        // }

        // var price = this.props.price * this.state.qtd;
        // total = { price: price, quantity: this.state.qtd };
        // events = {
        //     banner_app: this.props.banner_app,
        //     installments: this.props.installments,
        //     max_purchase: this.props.max_purchase,
        //     name: this.props.event_name,
        //     tickets: tickets,
        //     unique_number: this.props.unique_number
        // };
        // cart = { events: events, total: total };
        // localStorage.setItem('cart', JSON.stringify(cart));
        // console.log(localStorage.getItem('quantity'));
        if (localStorage.getItem('quantity') >= this.props.max_purchase) {
            this.setState({ showAddButton: false });
        }

    }
    removeItem() {
        if (this.state.qtd > 0) {
            this.setState({ qtd: this.state.qtd -= 1 });
        }
        
        if (this.state.qtd === 0) {
            quantity = [];
            quantity.pop();
            quantity.length = '';
            localStorage.removeItem('quantity');
            // this.setState({ showRemoveButton: true });
        } else{
            // this.setState({ showAddButton: true });
            localStorage.setItem('qtd', this.state.qtd);
            quantity.push(parseInt(this.state.qtd));
            // quantity = JSON.parse(localStorage.getItem('quantity'));
            localStorage.setItem('quantity', this.state.qtd);
        }

        console.log(localStorage.getItem('quantity'));
        if(localStorage.getItem('quantity') >= this.props.max_purchase){
            // this.setState({ showRemoveButton: false });
        }

        

        // cart = JSON.parse(localStorage.getItem('cart'));
        
        // if (cart.events.tickets.indexOf(this.props.tickets)) {
        //     localStorage.removeItem('cart');
        //     console.log('retirou');
        //     var price = this.props.price * this.state.qtd;
            
        //     total = { price: price, quantity: this.state.qtd };
        //     events = {
        //         banner_app: this.props.banner_app,
        //         installments: this.props.installments,
        //         max_purchase: this.props.max_purchase,
        //         name: this.props.event_name,
        //         tickets: tickets
        //     };
        //     cart = { events: events, total: total };
        //     localStorage.setItem('cart', JSON.stringify(cart));
        //     console.log(cart.events.tickets.indexOf(this.props.tickets));
        // }
        // console.log(cart.events.tickets);
        console.log(this.state.showAddButton);
    }
    componentDidMount() {
        //     const { id } = this.props.event_id;
        //     api.get(`event/${this.props.event_id}`)
        //         .then(res => {

        //             const event = res.data.data;
        //             console.log(event);
        //             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})
        //             )
        //         })
    }

    render() {
        return (
            <div>
                {
                    !this.state.showRemoveButton ?
                        <button className="minus" onClick={() => this.removeItem()}>
                            <i className="fas fa-minus"></i>
                        </button>
                        :
                        <div className="space-button"></div>
                }
                <input className="qtd" type="text" value={this.state.qtd} name='qtd' onChange={() => this.handleChange()} readOnly />
                {
                    this.state.showAddButton ?
                        <button className='plus' onClick={() => this.addItem()} >
                            <i className="fas fa-plus"></i>
                        </button>
                        : 
                        <div className="space-button"></div>
                }
            </div>
        )
    }
}

export default ChooseQuantity;

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

import './Event.css';
import '../../components/Css/App.css';
import ChooseQuantity from '../../components/ChooseQuantity/ChooseQuantity.js';

class Event extends Component {
    constructor(props){
        super(props);
        this.state = {
            event: {},
            dates: [],
            tickets: [],
            choose_quantity: 0,
            qtd: 0,
        }
    }
            
    componentDidMount() {
        const { id } = this.props.match.params;
        api.get(`event/${id}`)
            .then(res => {
                const event = res.data.data;
                this.setState({ event });
                console.log(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})
                )
            })
    }

    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, j) => 
                                        <div className="row" key={i}>
                                            <div className="col-8">
                                                <h5 className="lot-name">{ lot.name }</h5>
                                                <h6 className="lot-price">
                                                    R$ { lot.price.replace('.', ',') } <br />
                                                    <small>(R$ { lot.price.replace('.', ',') } + R$ { lot.price_tax.replace('.', ',') })</small>
                                                </h6>
                                            </div>
                                            <div className="col-4">
                                                <ChooseQuantity event_id={this.state.event.id} unique_number={ lot.unique_number } price={ lot.price } banner_app={ this.state.event.banner_app } max_purchase={this.state.event.max_purchase} event_name={this.state.event.name} tickets={ ticket.lot } />
                                            </div>
                                        </div>
                                    )}
                                    <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>3 INGRESSOS</h6>
                        <h5>R$ 16,00</h5>
                    </div>
                    <Link className="col col-purchase" to="/">
                        Comprar
                    </Link>
                </div>
            </div>
        )
    }
}

export default Event;

enter image description here

2 个答案:

答案 0 :(得分:1)

我注意到您正在使用

!this.state.showRemoveButton ?

在添加按钮上

this.state.showAddButton ?

您应该尝试删除!用于showRemoveButton。

答案 1 :(得分:1)

我创建了一个具有所需功能的示例小型项目。

基本上,您需要将状态保留在一个单独的组件中-父组件。 您不应该使用localStorage。 我使用一对ticket.uniqueId和lot.uniqueId作为selectedValue的键:

state = {
  selectedQuantities: {
    'ticket_1/lot_1': 3,
    'ticket_1/lot_2': 4,
  }
}

然后将选择内容传递给ChooseQuantity组件

<ChooseQuantity
  ...
  value={this.state.selectedQuantities[`${ticketUniqueId}${separator}${lotUniqueId}`}
/>

然后ChooseQuantity组件将类似于以下内容:

import React from 'react'

const ChooseQuantity = ({maxValue, value, onChange}) => {
  const shouldIncrement = value < maxValue
  const shouldDecrement = value > 0

  const decrement = () => {
    if (shouldDecrement) {
      onChange(value - 1)
    }
  }
  const increment = () => {
    if (shouldIncrement) {
      onChange(value + 1)
    }
  }

  const decrementButton = shouldDecrement ? (
    <button style={buttonStyle} onClick={decrement}>
      -
    </button>
  ) : null

  const incrementButton = shouldIncrement ? (
    <button style={buttonStyle} onClick={increment}>
      +
    </button>
  ) : null

  return (
    <div style={containerStyle}>
      {decrementButton}
      <span style={valueStyle}>{value}</span>
      {incrementButton}
    </div>
  )
}

ChooseQuantity.defaultProps = {
  value: 0,
  maxValue: 4,
}

const containerStyle = {
  display: 'flex',
  flexDirection: 'row',
  alignItems: 'center',
}

const buttonStyle = {
  height: '20px',
  margin: '0 5px',
}

const valueStyle = {
  margin: '0 5px',
}

export default ChooseQuantity;

在App组件(父级)中,有一个Checkout按钮,其中state.selectedQuantities对象被转换为对象数组,以便您可以使用它向后端创建API请求以完成订单:

[
  {
    "ticketId": "ticket_1",
    "lotId": "lot_1",
    "quantity": 3,
  },
  {
    "ticketId": "ticket_1",
    "lotId": "lot_2",
    "quantity": 4,
  },
]

这是一个有效的示例:https://codesandbox.io/s/react-codesandbox-tsrwc

旁注:避免在this.setState()之后使用this.setState()多次。尝试对每个事件一次使用this.setState()(点击,悬停,API响应等)