ReactJS: необходимо изменить стиль карты с помощью функции onClick - PullRequest
0 голосов
/ 05 марта 2019

Я знаю, что позже понадобится рефакторинг, чтобы разделить вещи на их собственные компоненты, но в данный момент у меня не хватает времени, и мне нужно подключить все как есть. Я использовал array.map () для создания элементов карточки из объекта JSON, который я использую для тестирования. Я пытаюсь использовать функцию onClick на карте <div>, чтобы сохранить некоторую идентифицируемую информацию, например, «offerid», в состояние компонента, а затем проверить, соответствует ли идентификатор в состоянии текущей карте. Если он совпадает, я хочу добавить cardActive в качестве className на div, чтобы только эта конкретная карта меняла цвет. Я не уверен, как это сделать. Как и сейчас, все стили карт обновляются независимо от того, какая карта выбрана. Компонент My React и соответствующий CSS перечислены ниже. Любая помощь будет высоко ценится

Реагировать

import React, { Component } from 'react';
import Grid from '@material-ui/core/Grid';
import './Button.css';

class UsersList extends Component {
    constructor(){
        super();

        this.state = {
            cardActive: false,

            customers:
            [
                {
                    "CustomerId": "1",
                    "LastName": "Doe",
                    "FirstName": "Jane",
                    "Address": {
                      "Address1": "1811 Chestnut Street",
                      "Address2": null,
                      "City": "Philadelphia",
                      "State": "Pennsylvania",
                      "Zip": "19103"
                    },
                    "Offers": [
                      {
                        "OfferId": "Offer1",
                        "Name": "Offer 1",
                        "Products": [
                          {
                            "ProductId": 1,
                            "ProductName": "Stuff"
                          },
                          {
                            "ProductId": 2,
                            "ProductName": "More stuff"
                          }
                        ],
                        "Price": "$1"
                      },
                      {
                        "OfferId": "Offer2",
                        "Name": "Offer 2",
                        "Price": "$2",
                        "Products": [
                          {
                            "ProductId": 3,
                            "ProductName": "A lot of stuff"
                          },
                          {
                            "ProductId": 4,
                            "ProductName": "And then there was stuff"
                          }
                        ]
                      },
                      {
                        "OfferId": "Offer3",
                        "Name": "Offer 3",
                        "Price": "$3",
                        "Products": [
                          {
                            "ProductId": 5,
                            "ProductName": "Good grief would you look at all this stuff"
                          },
                          {
                            "ProductId": 5,
                            "ProductName": "What a great deal for stuff"
                          }
                        ]
                      }
                    ]
                  }
              ]
        }
    }

    selectCard(){
        this.setState({ cardActive: !this.state.cardActive })
    }


    render (){
        let card_class = this.state.cardActive ? "cardActive" : "card";
        return (
            <div>
                {this.state.customers.map((customer, index) => {
                    return  <div key={index + customer.CustomerId}>
                                <h2>Customer</h2>
                                <hr></hr>
                                    <h3 >Name: {customer.LastName}, {customer.FirstName}</h3>
                                    <h3 >Customer ID: {customer.CustomerId}</h3>
                                    <h3 >
                                    Address: 
                                    <br></br>
                                    {customer.Address.Address1}
                                    <br></br>
                                    {customer.Address.City}, {customer.Address.State} {customer.Address.Zip} 
                                    </h3>
                                    <br></br>
                                    <h2>Available Offers</h2>
                                    <Grid container spacing={24} justify="center"> 
                                    {customer.Offers.map((Offer,index) => {
                                        return <div key={index + Offer.OfferId} onClick={this.selectCard.bind(this)}>
                                                <Grid item xs={12}>
                                                <div className="card" class={card_class}>
                                                    <div className="container">
                                                        <h5><b>{Offer.OfferId}</b></h5> 
                                                        <h2>{Offer.Name}</h2>
                                                        {Offer.Products.map((Product, index) => {
                                                            return <div key={index + Product.ProductId}>
                                                                    <p>+ {Product.ProductName}</p>
                                                                  </div>

                                                        })}
                                                        <h3>{Offer.Price}</h3> 
                                                    </div>
                                                </div>
                                                </Grid>
                                            </div>
                                    })}

                                    </Grid>

                            </div>

                })}
                <button className="navbuttonSelected">Submit</button>
            </div>
        )
    }
}

export default UsersList

CSS

  .card {
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
    transition: 0.3s;
    border-radius: 5px; /* 5px rounded corners */
    margin-left: 70px;
    margin-right: 70px;
    margin-bottom: 5%;
    cursor: pointer;
  }

  .cardActive {
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
    transition: 0.01s;
    border-radius: 5px; /* 5px rounded corners */
    margin-left: 70px;
    margin-right: 70px;
    margin-bottom: 5%;
    background: #0c72c5 !important;
    color: white !important;
    cursor: pointer;
  }

  .cardActive:hover {
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
  }

  .card:hover {
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
  }

Ответы [ 3 ]

1 голос
/ 05 марта 2019

Установить идентификатор выбранной карты:

selectCard(offerId) {   
  this.setState({ cardActive: offerId });
}

изменить способ вызова onClick и применить определенный класс, когда Offer.OfferId === this.state.cardActive

return (  
 <div
   key={index + Offer.OfferId}
   onClick={() => this.selectCard(Offer.OfferId)}
 >
   <Grid item xs={12}>
     <div
      className={Offer.OfferId === this.state.cardActive ? "cardActive" : "card"}>

Рабочий пример: https://codesandbox.io/s/mjryv01528

0 голосов
/ 05 марта 2019
...
constructor(){
    super();

    this.state = {
        cardActive: "",

        customers: [...]
    }
    this.selectCard = this.selectCard.bind(this);
    this.getCardClass = this.getCardClass.bind(this);
}

selectCard(offerId){
    this.setState({ cardActive: offerId })
}

getCardClass(offerId) {
    const { cardActive } = this.state;
    return offerId === cardActive ? 'cardActive' : 'card';
}

render() {
...
    customer.Offers.map((Offer,index) => {
        return <div key={index + Offer.OfferId} onClick={() => this.selectCard(Offer.OfferId)}>
            <div item xs={12}>
            <div className="card" class={this.getCardClass(Offer.OfferId)}>
                <div className="container">
                    <h5><b>{Offer.OfferId}</b></h5> 
                    <h2>{Offer.Name}</h2>
                    {Offer.Products.map((Product, index) => {
                        return <div key={index + Product.ProductId}>
                                <p>+ {Product.ProductName}</p>
                              </div>

                    })}
                    <h3>{Offer.Price}</h3> 
                </div>
            </div>
            </div>
        </div>
    })
...

}

Здесь выбранная карта хранится в состоянии, а не просто true или false.Вспомогательный метод selectCard устанавливает значение cardActive, а getCardClass определяет класс выбранной карты.

0 голосов
/ 05 марта 2019

Я могу предложить два подхода для решения вашей проблемы.

Подход 1:

  • В вашем методе selectCard, в дополнение к cardActive, сохраните идентификатор карты вгосударство.

  • В вашем методе рендеринга, в функции карты, рассмотрите Id (сохраненный в состоянии) также для применения вашего класса cardActive.

  • При таком подходе выне сможет выбрать несколько карт одновременно.Только одна карта будет иметь класс cardActive, а другие - нет.
  • Кроме того, вам необходимо убедиться, что вы устанавливаете Id в состояние только при выбранной карте.Не тогда, когда он отменен.

Approach2:

  • В объекте предложений клиента, помимо наличия всех существующих полей, добавьте свойство isActive и используйте его в своемМетод сопоставления либо для установки класса cardActive, либо для обычного класса.
  • Всякий раз, когда карта выбрана, обновите свойство isActive выбранной карты (вы можете передать offerObject методу selectCard и обновить свойство isActive в нем или передать его.уникальный идентификатор и используйте объект своих клиентов и обновите свойство isActive выбранного объекта.
  • При таком подходе можно выбрать несколько карт, поскольку вы поддерживаете isActive на каждом уровне клиента, а не одну переменную cardActive.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...