简体   繁体   中英

Trying to get a counter to work with React and multiple components

I am working on trying to get this counter for pintsLeft to work. This is my first project with React and I feel that I am either not passing the property of the array correctly or my function code is not set correctly.

^^^^KegDetail.js^^^^
 import React from "react";
import PropTypes from "prop-types";

function KegDetail(props){
  const { keg, onClickingDelete} = props 
  
  return (
    <React.Fragment>
    <hr/>
    <h2>{keg.name} Made By {keg.brewery}</h2>
    <p>abv {keg.abv}</p>
    <h3>price {keg.price}</h3>
    <p>{keg.pintsLeft} total pints left</p> {/* Make this a percentage */}
    <hr/>
    <button onClick={ props.onClickingEdit }>Update Keg</button>
    <button onClick={()=> onClickingDelete(keg.id) }>Delete Keg</button>
    <button onClick={()=> this.onSellingPint()}>Sell A Pint!</button>
  </React.Fragment>
  );
}

KegDetail.propTypes = {
  keg: PropTypes.object,
  onClickingDelete: PropTypes.func,
  onClickingEdit:PropTypes.func,
  onSellingPint:PropTypes.func
}

export default KegDetail;

That was my KegDetail.js

import React, {useState} from "react";
import NewKegForm from "./NewKegForm";
import DraftList from "./DraftList";
import KegDetail from "./KegDetail";
import EditKegForm from "./EditKegForm";

class DraftControl extends React.Component {

  constructor(props){
    super(props);
    this.state = {
      kegFormVisibleOnPage: false,
      fullDraftList: [],
      selectedKeg: null,
      editing: false,
      pints: 127,
      
      
      
      
      
      
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleSellingPint = this.handleSellingPint.bind(this);
    
  
  }

  handleClick = () => {
    if (this.state.selectedKeg != null){
      this.setState({
        kegFormVisibleOnPage: false,
        selectedKeg: null,
        editing: false
      });
    } else {
      this.setState(prevState => ({
        kegFormVisibleOnPage: !prevState.kegFormVisibleOnPage,
      }));
    }
  }

  handleSellingPint = () => {
   this.setState({
     pints:this.state.pints-1
   })
  };

render() {
    let currentlyVisibleState = null;
    let buttonText = null;
    
    if (this.state.editing){
      currentlyVisibleState = <EditKegForm keg = {this.state.selectedKeg} onEditKeg = {this.handleEditingKegInDraftList} />
      buttonText = "Return to the Draft List"
    }
    else if (this.state.selectedKeg != null){
      currentlyVisibleState = <KegDetail keg = {this.state.selectedKeg} onClickingDelete = {this.handleDeletingKeg}
      onClickingEdit = {this.handleEditClick} onSellingPint = {this.handleSellingPint}/>
      buttonText = "Return to the Keg List"

My DraftControl.js code

I don't know what I am doing wrong. I cant get the keg.pintsLeft to pass a number when I console.log, So I may be targeting it incorrectly.

Thanks again!

Try it like this:

handleSellingPint = () => {
   this.setState(prevState => {
     return {
         pints: prevState.pints-1
     }
   })
};

edit

Also, you invoke the onSellingPint() in a wrong way.

  1. It's not a class component, so React doesn't know what does this refer to.
  2. The function itself is passed in as a prop, so you should reference it like this: <button onClick={() => props.onSellingPint() />
 handleSellingPint = (id) => {
    const clonedArray = [...this.state.fullDraftList]
    for (let i = 0; i < this.state.fullDraftList.length; i++){
      if (clonedArray[i].id === id){
        clonedArray[i].pintsLeft -= 1
      }
    }
    this.setState({
          fullDraftList: clone
    });
  }

Is what I came up with.

Since you are alteriting a state within an array, you need to clone the array and work on that array, not the "real" one.

Thanks for all your help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM