Как использовать состояние React Redux для условного отображения и отключения кнопки - PullRequest
2 голосов
/ 16 июня 2020

Я сделал корзину покупок с помощью React-Redux. Все работает как надо, но вот с одной проблемой борюсь. Это меняет кнопку «Добавить в корзину», когда товар добавляется в корзину. Я хочу, чтобы эта кнопка была отключена, или изменила ее в кнопке «Удалить элемент».

Как я могу изменить это после добавления элемента?

My Reducer («ADD_TO_CART» и «REMOVE_ITEM»):


    import bg6 from '../../images/bg6.svg'
    import bg7 from '../../images/bg7.svg'
    import bg8 from '../../images/bg8.svg'

    const initState = {
    items: [
        { id: 1, title: 'Landing Page', desc: "Template", price: 10, img: bg6 },
        { id: 2, title: 'Adidas', desc: "Lore", price: 10, img: bg7 },
        { id: 3, title: 'Vans', desc: "Lorem ip", price: 10, img: bg8 },
    ],
    addedItems: [],
    total: 0,
    }

    const cartReducer = (state = initState, action) => {

    if (action.type === "ADD_TO_CART") {
        let addedItem = state.items.find(item => item.id === action.id)
        //check if the action id exists in the addedItems
        let existed_item = state.addedItems.find(item => action.id === item.id)
        if (existed_item) {
            addedItem.quantity = 1
            return {
                ...state,
                total: state.total + addedItem.price
            }
        }
        else {
            let addedItem = state.items.find(item => item.id === action.id)
            addedItem.quantity = 1;
            //calculating the total
            let newTotal = state.total + addedItem.price

            return {
                ...state,
                addedItems: [...state.addedItems, addedItem],
                total: newTotal
            }

        }
    }
    if (action.type === "REMOVE_ITEM") {
        let itemToRemove = state.addedItems.find(item => action.id === item.id)
        let new_items = state.addedItems.filter(item => action.id !== item.id)
        //calculating the total
        let newTotal = state.total - (itemToRemove.price * itemToRemove.quantity)
        return {
            ...state,
            addedItems: new_items,
            total: newTotal
        }
    }

    else {
        return state
    }
    }

    export default cartReducer

My Home Component where i want to change the button:

    import React, { Component } from 'react';
    import { connect } from 'react-redux'
    import { addToCart, removeItem } from '../../../store/actions/cartActions'
    import { withStyles } from '@material-ui/core/styles';
    import { Link, Redirect, withRouter, generatePath } from 'react-router-dom'
    import CardActions from '@material-ui/core/CardActions';
    import CardContent from '@material-ui/core/CardContent';
    import CardMedia from '@material-ui/core/CardMedia';
    import CssBaseline from '@material-ui/core/CssBaseline';
    import Grid from '@material-ui/core/Grid';
    import Typography from '@material-ui/core/Typography';
    import Container from '@material-ui/core/Container';
    import Button from '@material-ui/core/Button';
    import Card from '@material-ui/core/Card';
    import Appbar from '../../home/Appbar'
    import CheckIcon from '@material-ui/icons/Check';
    import DeleteIcon from '@material-ui/icons/Delete';


    const styles = theme => ({
      main: {
        backgroundColor: '#121212',
        maxHeight: 'auto',
        width: '100%',
        padding: '0',
        margin: '0',
      },

      cardGrid: {
        height: "auto",
        paddingTop: theme.spacing(8),
        paddingBottom: theme.spacing(8),
      },
      card: {
        backgroundColor: "#272727",
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
      },
      cardMedia: {
        paddingTop: '56.25%', // 16:9
      },
      cardContent: {
        flexGrow: 1,
      },

    });





    class Home extends Component {


      render() {
        const { classes, items, addedItems, addedItemID } = this.props
        const { } = this.state
        console.log(addedItemID)

        let allItems =
          items.map(item => {
            return (

              <Grid item key={item.id} xs={12} sm={6} md={4}>
                <Card className={classes.card}>
                  <CardMedia
                    className={classes.cardMedia}
                    image={item.img}
                    alt={item.title}
                    title={item.title}
                  />
                  <CardContent className={classes.cardContent}>
                    <Typography gutterBottom variant="h5" component="h2">
                      {item.title} {item.price}
                    </Typography>
                    <Typography>
                      {item.desc}
                    </Typography>
                  </CardContent>
                  <CardActions className={classes.cardActions}>

                    <Button
                        onClick={() => { this.props.addToCart(item.id) }}
                        style={{ color: "#d84", border: "1px solid #d84" }}
                        size="small"
                        color="primary"
                        disables={} //// HERE I NEED TO DISABLE BUTTON WHEN ITEM IS ADDED ////
                        >
                            Add to Cart //// THIS NEEDS TO BE DELETE ITEM ////
                    </Button>

                  </CardActions>
                </Card>
              </Grid>
            )
          })

        return (
          <React.Fragment>
            <CssBaseline />
            <Appbar />
            <main className={classes.main}>
              <Container className={classes.cardGrid} maxWidth="lg">
                <Grid container spacing={4}>
                  {allItems}
                </Grid>
              </Container>
            </main>
          </React.Fragment>


        )
      }

    }


    const mapStateToProps = (state) => {
      return {
        items: state.cartReducer.items,
        addedItems: state.cartReducer.addedItems,
        addedItemID: state.cartReducer.addedItemID,
      }
    }
    const mapDispatchToProps = (dispatch) => {

      return {
        addToCart: (id) => { dispatch(addToCart(id)) },
        removeItem: (id) => { dispatch(removeItem(id)) },
      }
    }

    export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Home)));

Кажется, я не могу оберните меня вокруг этого. Надеюсь, вы можете помочь.

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 16 июня 2020

Вы можете использовать this.props.addedItems и проверить, есть ли в нем элемент, который вы пытаетесь добавить, добавить метод и использовать его для состояния Disabled.

const isItemExist = (itemToFindId) => {
        return this.props.addedItems.findIndex(item => item.id === itemToFindId) === -1;
    }

    <Button
      onClick={() => { this.props.addToCart(item.id) }}
      style={{ color: "#d84", border: "1px solid #d84" }}
      size="small"
      color="primary"
      disables={()=>isItemExist(item.id)} //// HERE I NEED TO DISABLE BUTTON WHEN ITEM IS ADDED ////
     >
     Add to Cart //// THIS NEEDS TO BE DELETE ITEM ////
   </Button>

вы также можете использовать тот же лог c и создайте другую кнопку, используйте

{isItemExist(item.id) ? <RemoveCartButton/> : <AddToCartButton/>}

дайте мне знать, если у вас возникнут другие проблемы.

Я постараюсь их решить

0 голосов
/ 16 июня 2020

, вы можете сделать это, проверив addedItems длину или total значение.
прежде всего, включите total в свою mapStateToProps функцию:

 const mapStateToProps = (state) => {
  return {
    items: state.cartReducer.items,
    addedItems: state.cartReducer.addedItems,
    addedItemID: state.cartReducer.addedItemID,
    total: state.cartReducer.total
  }
}

затем извлеките это из реквизита компонента:

const { classes, items, addedItems, addedItemID, total } = this.props;

теперь ваша кнопка может быть примерно такой:

<Button
    onClick={() => { this.props.addToCart(item.id) }}
    style={{ color: "#d84", border: "1px solid #d84" }}
    size="small"
    color="primary"
    disabled={total > 0 || addedItems.length > 0 ? true : false}
>
    {total > 0 || addedItems.length > 0 ? "Delete Item" : "Add to Cart" } 
</Button>
0 голосов
/ 16 июня 2020

используйте условную отрисовку в JSX: сначала создайте дополнительное состояние для обработки состояния кнопки. Я называю это, например, is_add_to_cart, и каждый раз, когда нажимается кнопка в обоих разделах редуктора, мы должны изменить значение is_add_to_cart на противоположное значение, я имею в виду, если вы изначально установили: is_add_to_cart : true в состоянии инициализации, тогда вы должны вернуть его значение и это примерно так: is_add_to_cart = !is_add_to_cart в вашем новом состоянии.

в возвращаемой части кода jsx мы должны выполнить условный рендеринг, вот как это выглядит:

is_add_to_cart ? <Button . . . >Add To Cart</Button> 
               : <Button . . . >Delete Item</Button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...