Hide the Balance exercise

Why am I receiving this error: TypeError: this.props.handleUpdatePrice is not a function … it points to line 39 on my Coin.js file. I’ll link all of the relevant contracts below.

App.js inherits Coinlist, which inherits Coin… so that’s how App.js communicates with the Coin contract

I have literally copied Zolt’s code verbatim, but I cannot get the “update price” button to properly work. Here is my main App.js file

import React from 'react';
import AccountBalance from './components/AccountBalance/AccountBalance';
import CoinList from './components/CoinList/CoinList';
import ExchangeHeader from './components/ExchangeHeader/ExchangeHeader';
import styled from 'styled-components';

const Div = styled.div`
  text-align: center;
  background-color: #440066;
  color: #E6EAFF;
  `

class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      balance: 10000,
      showBalance: true,
      coinData: [
        { name: "Bitcoin",
          ticker: "BTC",
          balance: 0.5,
          price: 34000 },
        { name: "Ethereum",
          ticker: "ETH",
          balance: 5,
          price: 2100
        },
        {name: "Cardano",
          ticker: "ADA",
          balance: 5000,
          price: 1.25
        },
        {name: "USDC",
          ticker: "USDC",
          balance: 2500,
          price: "1.00"
        },
      ]
    }
    this.handleUpdatePrice = this.handleUpdatePrice.bind(this);
    this.balanceVisibility = this.balanceVisibility.bind(this);
  }

  balanceVisibility(){
    this.setState(function(oldState){
      return{
        ...oldState,
        showBalance: !oldState.showBalance
    }});
  }

  handleUpdatePrice(valueTicker){
    const newCoinPrice = this.state.coinData.map(function({ticker, name, price}) {
      let newPrice = price;
      if(valueTicker === ticker){
        const randomPercent = 0.995 + Math.random() * 0.01;
        newPrice = (newPrice * randomPercent).toFixed(2);
      }
    return {
      ticker,
      name,
      price: newPrice
    }
  });
  this.setState({coinData : newCoinPrice});
}

  render(){
    return (
      <Div>
          <ExchangeHeader/>
          <AccountBalance
            amount= {this.state.balance}
            showBalance={this.state.showBalance}
            balanceVisibility= {this.balanceVisibility}/>
          <CoinList
            coinData= {this.state.coinData}
            showBalance = {this.state.showBalance}
            handleUpdatePrice={this.state.handleUpdatePrice}/>
      </Div>
    );
  }
}

export default App;

Here is the Coin file. In the handleClick(event) is where the error message will say “this.props. handleUpdatePrice is not a function.”

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const TD = styled.td`
  border: 1px solid #E6EAFF;
  width: 15vh;
`


class Coin extends Component {
  constructor (props){
    super(props);
    //.bind helps us bind the handleClick function that's outside of this constructor
    //into what's inside the constructor, access properties & set a new value (in this case, price)
    this.handleClick = this.handleClick.bind(this);

  }
  /*componentDidMount(){
    const callback = () => {
      const randomPercent = 0.995 + Math.random() * 0.01;
      //can't set this.state.price because it's already initialized
      //we use another function called 'this.setState' that inherently accesses current state and can re-initialize this.state
      //follow format below
      this.setState(({coinData : price}){
        //return the price as the object that it already is
        return {
          price: (price * randomPercent).toFixed(2)
        };
      });
    }
    //now, we use the callback we created
    setInterval(callback, 5000);
  } */

  handleClick(event){
    event.preventDefault();

    this.props.handleUpdatePrice(this.props.ticker);
  }

  render() {
    return (
      <tr>
        <TD>{this.props.name}</TD>
        <TD>{this.props.ticker}</TD>
        <TD>{this.props.price}</TD>
        {this.props.showBalance ? <TD>{this.props.balance}</TD> : <TD>***</TD>}
        <TD>
          <form action = "#" method = "POST">
            <button onClick = {this.handleClick}>Update Price</button>
          </form>
        </TD>
      </tr>
    );
  }
}

Coin.propTypes = {
  name: PropTypes.string.isRequired,
  ticker: PropTypes.string,
  price: PropTypes.number,
}

export default Coin;
1 Like

handleUpdatePrice is not a state defined variable. It is outside of state. So you should just have –
handleUpdatePrice={this.handleUpdatePrice}/>

This will solve your issue.

Happy Learning! :slight_smile:

1 Like

Looks good! Minor criticism - you might want to switch your ticker and name table headers around :stuck_out_tongue:

1 Like

I half expected React to be a relatively easy course compared to the others coming into it.
But man this is kicking my ass so far :man_facepalming:

App.js

import React from 'react';
import CoinList from './components/CoinList/CoinList';
import AccountBalance from './components/AccountBalance/AccountBalance';
import ExchangeHeader from './components/ExchangeHeader/ExchangeHeader';
import styled from 'styled-components';

const Div = styled.div`
  text-align: center;
  background-color: rgb(24, 24, 71);
  color: #cccccc;
`

class App extends React.Component {
  state = {
    balance: 10000,
    showBalance: true,
    coinData: [
      {
        name: "Bitcoin",
        ticker: "BTC",
        balance: 0.5,
        price: 9999.99
      },
      {
        name: "Ethereum",
        ticker: "ETH",
        balance: 32,
        price: 5000
      },
      {
        name: "Litecoin",
        ticker: "LTC",
        balance: 0,
        price: 2000
      }
    ]
  } 

  handleToggleShowBalance = () => {
    this.setState( function(oldState) {
      return {
        ...oldState,
        showBalance : !oldState.showBalance
      }
    });
  }

  handleRefresh = (valueChangeTicker) => {
    const newCoinData = this.state.coinData.map(function(values) {
      let newValues = {...values};
      if (valueChangeTicker === values.ticker) {
        const randomPercentage = 0.995 + Math.random() * 0.01;
          newValues.price *= randomPercentage
      }
      return newValues;
    });
    this.setState({coinData: newCoinData});
  }

  render() {
    return (
      <Div>
        <ExchangeHeader/>
        <AccountBalance 
          amount = {this.state.balance} 
          showBalance = {this.state.showBalance} 
          handleToggleShowBalance = {this.handleToggleShowBalance}/>
        <CoinList 
          coinData = {this.state.coinData} 
          handleRefresh = {this.handleRefresh} 
          showBalance = {this.state.showBalance}/>
      </Div>
    );
  }
}
    
export default App;

AccountBalance.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components'

const Section = styled.section`
    font-size: 1.5rem;
    background: transparent;
    border-radius: 3px;
    border: 2px solid palevioletred;
    color: palevioletred;
    margin: 0 1em;
    padding: 0.25em 1em;
`;

const ButtonBalance = styled.button`
    background: navy;
    border-radius: 3px;
    border: 2px solid palevioletred;
    color: palevioletred;
    margin: 0 1em;
    padding: 0.25em 1em;
`;

export default class AccountBalance extends Component {
    render() {
        const buttonText = this.props.showBalance ? "Hide Balance" : "Show Balance";
        let content = null;
        if (this.props.showBalance) {
            content = <>Balance: ${this.props.amount}</>
        }
        let balance = this.props.showBalance ? <span>Balance: ${this.props.amount}</span> : null;
        return (
            <Section>
                {content}
                <ButtonBalance onClick={this.props.handleToggleShowBalance}>{buttonText}</ButtonBalance>
            </Section>
        );
    }
}

AccountBalance.propTypes = {
    amount: PropTypes.number.isRequired
}

CoinList.jsx

import React, { Component } from 'react';
import Coin from '../Coin/Coin';
import styled from 'styled-components';

const CoinTable = styled.table`
  margin: 50px auto 50px auto;
  display: inline-block;
  font-size: 1.4rem;
`

export default class CoinList extends Component {
    render() {
        return (
                <CoinTable>
                <thead>
                    <tr>
                    <th>Name</th>
                    <th>Ticker</th>
                    <th>Price</th>
                    {this.props.showBalance ? <th>Balance</th> : null}
                    <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {
                    this.props.coinData.map(value =>
                    <Coin   key = {value.ticker}
                            handleRefresh = {this.props.handleRefresh}
                            name = {value.name}
                            ticker = {value.ticker}
                            balance = {value.balance}
                            showBalance = {this.props.showBalance}
                            price = {value.price}/>)
                    }
                </tbody>
                </CoinTable>
        )
    }
}

Coin.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Td = styled.td`
border: 1px solid #cccccc;
width: 25vh;
`;

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;
`;

export default class Coin extends Component {

    handleClick = (event) => {
        event.preventDefault();
        this.props.handleRefresh(this.props.ticker);
    }

    render() {
        return (
            <tr>
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>${this.props.price}</Td>
                {this.props.showBalance ? <Td>{this.props.balance}</Td> : null}
                <td><Button onClick = {this.handleClick}>Refresh</Button></td>
            </tr>
        );
    }
}

Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired
}
3 Likes

Hi Malik,
Unfortunately, this has not solves my issue. What specific line were you talking about? Because the error message I received points to Coin.js, where in the handleclick(), I have a handleUpdatePrice()… THIS is where I get an error message saying “handleUpdatePrice() is not a function.”

I went and changed the “.state” thing you mentioned, but still no luck. Any other ideas?

same. getting absolutely smoked in this course

2 Likes

There’s aa strange comfort in knowing it’s not just me :sunglasses:

2 Likes

App.js

import React from 'react';
import './App.css';
import AppHeader from './components/AppHeader/AppHeader';
import CoinList from './components/CoinList/CoinList';
import AccountBalance from './components/AccountBalance/AccountBalance';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      balance: 1000,
      showBalance: false,
      coinData: [
        { name:"Bitcoin",      ticker:"BTC",  balance: 0.5,  price:35000.90 },
        { name:"Ethereum",     ticker:"ETH",  balance: 32.0, price:2123.55 },
        { name:"Tether",       ticker:"USDT", balance: 0,    price:1.0 },
        { name:"Ripple",       ticker:"XRP",  balance: 1000, price:0.2 },
        { name:"Bitcoin Cash", ticker:"BCH",  balance: 10.0, price:399.99 },
      ]
    }
    this.doCoinRefresh = this.doCoinRefresh.bind(this);
    this.doBalanceDisplay = this.doBalanceDisplay.bind(this);
  }

  doCoinRefresh(selectedTicker) {
    const newCoinData = this.state.coinData.map( ({ticker, name, price, balance}) => {
      let newPrice = price;
      if (ticker === selectedTicker) {
        const randomPercentage = 0.995 + Math.random() * 0.01;
        newPrice *= randomPercentage;
      }
      return {ticker, name, price:newPrice, balance};
    });
    this.setState({coinData: newCoinData}); // replaces only mentioned part
  }

  doBalanceDisplay(setBalanceDisplay) {
    this.setState({showBalance: setBalanceDisplay});
  }

  render() {
    return (
      <div className="App">
        <AppHeader />
        <AccountBalance amount={this.state.balance} showBalance={this.state.showBalance} doBalanceDisplay={this.doBalanceDisplay} />
        <CoinList coinData={this.state.coinData} showBalance={this.state.showBalance} doCoinRefresh={this.doCoinRefresh} />
      </div>
    );
  }
}

export default App;

AccountBalance.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const DivAccountBalance = styled.div`
    text-align: center;
`;

const SectionAccountBalance = styled.section`
    display: inline-block;
    font-size: 2rem;
    text-align: center;
    padding: 1rem 1rem 1.5rem 1rem;
    border: 2px solid grey;
`;

export default class AccountBalance extends Component {
    constructor(props) {
        super(props);
        this.btnBalanceDisplay = this.btnBalanceDisplay.bind(this);
    }

    btnBalanceDisplay(event) {
        event.preventDefault();
        this.props.doBalanceDisplay(!this.props.showBalance);
    }

    render() {
        const btnText = (this.props.showBalance ? 'Hide' : 'Show') + ' balance';
        return (
            <DivAccountBalance>
                <SectionAccountBalance>
                    <span style={{display:this.props.showBalance ? 'flex' : 'none'}}>Accountbalance: ${this.props.amount}</span>
                    <button onClick={this.btnBalanceDisplay}>{btnText}</button>
                </SectionAccountBalance>
            </DivAccountBalance>
        );
    }
}

AccountBalance.propTypes = {
    amount: PropTypes.number.isRequired
}

Coin.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const TdCoinRow = styled.td`
    border: 1px solid #ccc;
    width: 25vh;
`;

export default class Coin extends Component {
    constructor(props) {
        super(props);
        this.doCoinRefresh = this.doCoinRefresh.bind(this);
    }

    doCoinRefresh(event) {
        // Prevent the default action of submitting the form
        event.preventDefault();
        
        this.props.doCoinRefresh(this.props.ticker);
    }

    render() {
        return (
            <tr>
                <TdCoinRow>{this.props.name}</TdCoinRow>
                <TdCoinRow>{this.props.ticker}</TdCoinRow>
                <TdCoinRow>${this.props.price}</TdCoinRow>
                <TdCoinRow style={{display:this.props.showBalance ? 'block' : 'none'}}>${this.props.balance}</TdCoinRow>
                <TdCoinRow><button onClick={this.doCoinRefresh}>Refresh</button></TdCoinRow>
            </tr>
        );
    }
}

Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired,
    balance: PropTypes.number.isRequired
}

CoinList.jsx

import React, { Component } from 'react'
import Coin from '../Coin/Coin';

export default class CoinList extends Component {
    render() {
        return (
            <table className="coin-table">
            <thead>
                <tr><th>Name</th><th>Ticker</th><th>Price</th>
                <th style={{display:this.props.showBalance ? 'block' : 'none'}}>Balance</th>
                <th>Action</th></tr>
            </thead>
            <tbody>
              {
                this.props.coinData.map( ({name, ticker, price, balance}) => 
                  <Coin key={ticker} 
                  doCoinRefresh={this.props.doCoinRefresh}
                  showBalance={this.props.showBalance}
                  name={name} ticker={ticker} balance={balance} price={price} />
                )
              }
            </tbody>
          </table>
          );
    }
}
1 Like

I learned quite a bit from reading what others have posted here and from my initial attempts. I had struggled with the onclick event and how to tie it with both the balance and the column. It seems this course has so much in it, there may be a benefit to doing it twice to catch things that were missed.

2 Likes

Hide the Balance Exercise
Proposed solution.

App

import AccountBalance from './components/AccountBalance/AccountBalance';
import React from 'react'; 
import { v4 as uuidv4 } from 'uuid';
import CoinList from './components/CoinList/CoinList.jsx';
import Header from './components/Header/Header.jsx';

class App extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      balance: 10000,
      showBalance: false,
      coinData: [
                {
                  key: uuidv4(),
                  name: "Bitcoin" ,
                  ticker:"BTC",
                  balance: 1.5,
                  price: 34103.31
                },
                {
                  key: uuidv4(),
                  name: "Ethereum",
                  ticker: "ETH",
                  balance: 10.5,
                  price: 2157.73
                },
               {
                 key: uuidv4(),
                 name: "Binance Coin", 
                 ticker: "BNB",
                 balance: 1000,
                 price: 319.98
               },
              {
                key: uuidv4(),
                name: "Cardano",
                ticker: "ADA",
                balance: 2000,
                price: 1.35
              },
             {
               key: uuidv4(),
               name: "XRP", 
               ticker: "XRP",
               balance: 20,
               price: 0.634853
             },
            {
              key: uuidv4(),
              name: "Dogde Coin",
              ticker: "DODGE",
              balance: 0,
              price: 0.218369
            },
           {
             key: uuidv4(),
             name: "Polkadot",
             ticker: "DOT",
             balance: 10000,
             price: 15.68
           },
          {
            key: uuidv4(),
            name: "Uniswap", 
            ticker: "UNI",
            balance: 500,
            price: 20.89
          },
         {
           key: uuidv4(),
           name: "Bitcoin Cash",
           ticker: "BCH",
           balance: 0,
           price: 500.60
         },
        {
          key: uuidv4(),
          name: "Litecoin", 
          ticker: "LTC",
          balance: 100,
          price: 134.79
        },
        {
          key: uuidv4(),
          name: "Solana",
          ticker: "SOL",
          balance: 50000,
          price: 32.92
        },
        {
          key: uuidv4(),
          name: "Chainlink",
          ticker: "LINK",
          balance: 25750,
          price: 18.70
        },
        {
          key: uuidv4(),
          name: "Polygon",
          ticker: "MATIC",
          balance: 5000,
          price: 0.99
        },
        {
          key: uuidv4(),
          name: "Ethereum Classic",
          ticker: "ETC",
          balance: 0,
          price: 47.43
        },
        {
          key: uuidv4(),
          name: "Stellar",
          ticker: "XLM",
          balance: 0,
          price: 0.24
        },
        {
          key: uuidv4(),
          name: "Theta Network",
          ticker: "THETA",
          balance: 10,
          price: 0.24
        }
      ]
    };

    this.handleRefresh = this.handleRefresh.bind(this);
    this.handleBalanceVisability = this.handleBalanceVisability.bind(this);
  }

  handleBalanceVisability(Event){
    Event.preventDefault();
    this.setState( oldState => {
    return { 
            ...oldState,
             showBalance: !oldState.showBalance
           }
    });
  }

  handleRefresh(valueChangedTicker){
    const newCoinData = this.state.coinData.map(({ticker, name, price, balance}) => {
      let newPrice = price;
      if(valueChangedTicker === ticker){
        
        const randomPercentage = 0.995 + Math.random() * 0.01;
        newPrice = newPrice * randomPercentage; 
      }
      return {
        ticker,
        name,
        price: newPrice,
        balance
      }
      });
      //console.log(newCoinData);
      this.setState({coinData: newCoinData})
  }
  render()
    {
        return (
          <>
            <Header />
            <AccountBalance 
                amount={this.state.balance} 
                showBalance={this.state.showBalance} 
                handleBalanceVisability={this.handleBalanceVisability}
            />
            <CoinList 
                coinData={this.state.coinData} 
                showBalance={this.state.showBalance}
                handleRefresh={this.handleRefresh} 
            />
          </>
      
      );
  }
}

export default App;

Coin

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';



const Button = styled.button`
   background: black;
   border-radius: 3px;
   border: 2px solid darkgrey;
   color: white;
   margin: 0 1em;
   padding: 0.25em 1em;
  
    `;


    const Td = styled.td`
       border: 1px solid black;
       background-color: lightgrey;
       width: 25vh; 
    `;


export default class Coin extends Component {
   constructor(props){
       super(props);
       this.handleClick = this.handleClick.bind(this);
   }

   handleClick(Event){
       Event.preventDefault();

       this.props.handleRefresh(this.props.ticker);
   }

   
    render(){
        return (
            <tr>
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>${this.props.price}</Td>
                <Td>{this.props.balance}</Td>
                <Td>
                    <form action="#" method="POST">
                        <Button onClick={this.handleClick}>Refresh</Button>
                    </form>
                </Td>
            </tr>
        );
    }
    
}
//type checking.
Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired,
    balance: PropTypes.number.isRequired
}




coin list

import React, { Component } from 'react';
import styled from 'styled-components';
import Coin from '../Coin/Coin.jsx';
import { v4 as uuidv4 } from 'uuid';

const Table = styled.table`

    margin: 50px auto 50px 250px;
    display: inline-block;
    font-size: 1.2rem;

    `;

export default class CoinList extends Component{
    render(){
        return(
            <Table>
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Ticker</th>
                        <th>Price</th>
                       {this.props.showBalance ? <th>Balance</th> : null }
                    </tr>
                </thead>
                <tbody>
                    {
                        this.props.coinData.map( ({name, ticker, price, balance}) => 
                        <Coin 
                            key={uuidv4()}
                            handleRefresh={this.props.handleRefresh}
                            name={name} 
                            ticker={ticker}
                            balance={(this.props.showBalance ? balance : null)} 
                            price={price}
                          />)
                    }

                </tbody>
            </Table>
        );
    }
} 

AccountBalance

import React, { Component} from 'react';
import PropTypes from 'prop-types';

import styled from 'styled-components';

const Section = styled.section `
    text-align: left;
    font-size: 2rem;
    padding: 1.5rem 0 1.5rem 5rem;
`;

const Button = styled.button`
   background: black;
   border-radius: 3px;
   border: 2px solid darkgrey;
   color: white;
   margin: 0 1em;
   padding: 0.25em 1em;
  
    `;

export default class AccountBalance extends Component {

    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance'
        let balanceData = null;
        if(this.props.showBalance)
        {
           balanceData =  <>Balance: ${ this.props.amount }</>
        }
        return (
            <Section>
                {balanceData}
                <form action="#" method="POST">
                    <Button onClick={this.props.handleBalanceVisability}>{buttonText}</Button>
                </form>
            </Section>
        
        );
    }
}


AccountBalance.propTypes = {

    amount: PropTypes.number.isRequired
}

1 Like
  • App.js
import React from 'react';
import CoinList from './components/CoinList/CoinList';
import AccountBalance from './components/AccountBalance/AccountBalance';
import AppHeader from './components/AppHeader/AppHeader';
import styled from 'styled-components';

const Div = styled.div`
  text-align: center;
  background-color: rgb(22, 118, 156);
  color: antiquewhite;
`;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      balance: 10000,
      showBalance: true,
      coinData: [
        {
          name: 'Bitcoin',
          ticker: 'BTC',
          balance: 0.5,
          price: 9999.99
        },
        {
          name: 'Ethereum',
          ticker: 'ETH',
          balance: 32.0,
          price: 299.99
        },
        {
          name: 'Tether',
          ticker: 'USDT',
          balance: 0,
          price: 1.0
        },
        { 
          name: 'Ripple',
          ticker: 'XRP',
          balance: 1000,
          price: 0.2
        },
        {
          name: 'Bitcoin Cash',
          ticker: 'BCH',
          balance: 0,
          price: 298.99
        }
      ]
    }
    this.handleRefresh = this.handleRefresh.bind(this);
    this.handleBalanceVisibilityChange = this.handleBalanceVisibilityChange.bind(this);
  }

  handleBalanceVisibilityChange() {
    this.setState( function(oldState) {
      return {
        ...oldState,
        showBalance: !oldState.showBalance
      }
    });
  }

  handleRefresh(valueChangeTicker) {
    const newCoinData = this.state.coinData.map(function({ticker, name, price}) {
      let newPrice = price;
      if(valueChangeTicker === ticker) {
        const randomPercentage = 0.995 + Math.random() * 0.01;
        newPrice = newPrice * randomPercentage;
      }
      return {
        ticker,
        name,
        price: newPrice
      }
    });
    this.setState({coinData: newCoinData});
  }
  render() {
    return (
      <Div>
        <AppHeader />
        <AccountBalance 
          amount={this.state.balance} 
          showBalance={this.state.showBalance} 
          handleBalanceVisibilityChange={this.handleBalanceVisibilityChange}/>
        <CoinList 
          coinData={this.state.coinData} 
          showBalance={this.state.showBalance}
          handleRefresh={this.handleRefresh}/>
      </Div>
    );
  }
}

// to represent a number, fractional number -> put in brackets.


export default App;

I’m still don’t understand how props, prop drilling and lifting states up works but I’ll continue trying.

  • AcountBalance
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Section = styled.section`
    font-size: 2rem;
    text-align: left;
    padding: 1.5rem 5rem;
`;

export default class AccountBalance extends Component {
    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance';
        let content = null;
        if (this.props.showBalance) {
            content = <>Balance: ${this.props.amount}</>;
        }
        return (
            <Section>
                {content}
                <button onClick={this.props.handleBalanceVisibilityChange}>{buttonText}</button>
            </Section>
        );
    }
}

AccountBalance.propTypes = {
    amount: PropTypes.number.isRequired
  }
  • CoinList
import React, { Component } from 'react';
import Coin from '../Coin/Coin';
import styled from 'styled-components';

const Table = styled.table`
  margin: 50px auto 50px auto;
  display: inline-block;
  font-size: 1.4rem;
`;

export default class CoinList extends Component {
  render() {
    return (
      <Table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Ticker</th>
            <th>Price</th>
            {this.props.showBalance ? <th>Balance</th> : null}
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          {
            this.props.coinData.map(({name, ticker, price, balance}) =>
              <Coin key = {ticker}
                    handleRefresh = {this.props.handleRefresh}
                    name = {name}
                    ticker = {ticker}
                    showBalance = {this.props.showBalance}
                    balance = {balance}
                    price = {price} />
            )
          }
        </tbody>
      </Table>
    )
  }
}
  • Coin
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Td = styled.td`
  border: 1px solid #cccccc;
  width: 25vh;
`;

export default class Coin extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    event.preventDefault();
    this.props.handleRefresh(this.props.ticker);
  }
 
    render() {
        return (
            <tr>
              <Td>{this.props.name}</Td>
              <Td>{this.props.ticker}</Td> 
              <Td>${this.props.price}</Td>
              {this.props.showBalance ? <Td>{this.props.balance}</Td> : null}
              <Td>
                <form action="#" method="POST">
                  <button onClick={this.handleClick}>Refresh</button>
                </form>
              </Td>  
            </tr>
          );
    }
}

Coin.propTypes = {
  name: PropTypes.string.isRequired,
  ticker: PropTypes.string.isRequired,
  price: PropTypes.number.isRequired
}
2 Likes

Me too! So happy to know I was not the only one having the same feelings😁

2 Likes

Getting kicked to the curb here myself.

2 Likes

Wow!!! Challenging :grin:
App.js

import React from 'react';
import CoinList from './Components/CoinList/CoinList';
import AccountBalance from './Components/AccountBalance/AccountBalance';
import AppHeader from './Components/AppHeader/AppHeader';
import styled from 'styled-components';

const Div = styled.div`
  text-align: center;
  background-color: rgb(0, 65, 139);
  color: #cccccc;
`;

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          balance: 10000,
          showBalance: true,
          coinData: [
            {
              name: "Bitcoin",
              ticker: "BTC",
              balance: 0.5,
              price: 9999.99
            },
            {
              name: "Ethereum",
              ticker: "ETH",
              balance: 32.0,
              price: 299.99
            },
            {
              name: "Tether",
              ticker: "USDT",
              balance: 0,
              price: 1.0
            },
            {
              name: "Ripple",
              ticker: "XRP",
              balance: 1000,
              price: 0.2
            },
            {
              name: "Bitcoin Cash",
              ticker: "BCH",
              balance: 0,
              price: 297.99
            },
          ]
        }
        this.handleRefresh = this.handleRefresh.bind(this);
        this.handleBalanceVisibilityChange = this.handleBalanceVisibilityChange.bind(this);
      }
      handleBalanceVisibilityChange() {
        this.setState( function(oldState) {
          return {
            ...oldState,
            showBalance: !oldState.showBalance,
          }
        });
      }
      handleRefresh(valueChangeTicker) {
        const newCoinData = this.state.coinData.map(function({ticker, name, price} ) {
          let newPrice = price;
          if ( valueChangeTicker === ticker ) {
          const ramdomPercentage = 0.995 + Math.random() * 0.01;
          newPrice = newPrice * ramdomPercentage;
        }
        return {
          ticker,
          name,
          price: newPrice,
          }
       });

        
       this.setState({ coinData: newCoinData});
      }
    render() {
    return (
        <Div className="App">
        <AppHeader />
        <AccountBalance 
          amount={this.state.balance} 
          showBalance={this.state.showBalance} 
          handleBalanceVisibilityChange={this.handleBalanceVisibilityChange}/>
        <CoinList 
        coinData={this.state.coinData} 
        showBalance={this.state.showBalance}
        handleRefresh={this.handleRefresh} />
          </Div> 
    );
  }

}
          
export default App;

AccountBalance.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Section = styled.section`
    boder: 1px solid red;
    font-size: 2rem;
    text-aligh: left;
    padding: 1.5rem 0 1.5rem 5rem;
`;
export default class AccountBalance extends Component {
    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance';
        let content = null;
        if (this.props.showBalance) {
            content = <>Balance: ${this.props.amount}</>;
        }
        return (
            <Section>
                {content}
            Balance: ${this.props.amount}
            <button onClick={this.props.handleBalanceVisibilityChange}>{buttonText}</button>
            </Section>
        );
    }
}

AccountBalance.pricepropTypes = {
    amount: PropTypes.number.isRequired,
    
  }

CoinList.jsx

import React, { Component } from 'react'
import Coin from '../Coin/Coin';
import styled from 'styled-components'; 

const Table = styled.table`
    margin: 50px auto 50px auto;
    display: inline-block;
    font-size: 1.4rem;
`;

export default class CoinList extends Component {
    render() {
        return (
            <Table>
          <head>
            <tr>
                <th>Name</th>
                <th>Ticker</th>
                <th>Price</th>
                {this.props.showBalance ? <th>Balance</th> : null}
                <th>Actions</th>
                </tr>
            </head>
            <tbody>
                {
                  this.props.coinData.map( ({name, ticker, balance, price}) =>
                    <Coin key={ticker} 
                     handleRefresh={this.props.handleRefresh}
                     name={name} 
                     ticker={ticker} 
                     balance={balance}
                     showBalance={this.props.showBalance}
                     price={price} />
                    )
                  }
                </tbody>
               </Table>
                
        
        )
    }
}

Coin.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Td = styled.td`; 
  border; 1px solid #cccccc; 
  width; 25vh; 
  `;

 export default class Coin extends Component {
  constructor(props) {
      super(props);
        this.handleClick = this.handleClick.bind(this);
    }

 handleClick(event) {
   //Prevent the default action of submitting the form 
   event.preventDefault();
   
   this.props.handleRefresh(this.props.ticker);
  }

       render () {
            return (
            
              <tr>
              <Td>{this.props.name}</Td>
              <Td>{this.props.ticker}</Td>
              <Td>${this.props.price}</Td>
              {this.props.showBalance ? <Td>{this.props.balance}</Td> : null }
              <Td>
                <form action="#" method= "POST">
                <button onClick={this.handleClick}>Refresh</button>
                </form>
                </Td>
                </tr>
                
            );
    }
}

Coin.propTypes = {
  name: PropTypes.string.isRequired,
  ticker: PropTypes.string.isRequired,
  price: PropTypes.number.isRequired,
}
1 Like

App.js

import React from 'react';
import './App.css';
import AccountBalance from './components/AccountBalance/AccountBalance';
import CoinList from './components/CoinList/CoinList';
import CoinHeader from './components/CoinHeader/CoinHeader';

  class App extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        balance: 11000,
        toggleBalanceDisplay: true,
        coinData: [
          {
            name: 'Bitcoin',
            ticker: 'BTC',
            balance: 0.5,
            price: 41034.23
          },
          {
            name: 'Ethereum',
            ticker: 'ETH',
            balance: 32.0,
            price: 2122.49
          },
          {
            name: 'Monero',
            ticker: 'XMR',
            balance: 65.5,
            price: 238.08
          },
          {
            name: 'Cardano',
            ticker: 'ADA',
            balance: 5000.0,
            price: 1.27
          }
        ]
      }
      this.handleRefresh = this.handleRefresh.bind(this);
      this.toggleBalance = this.toggleBalance.bind(this);
    }

    handleRefresh(valueChangeTicker) {
      console.log(valueChangeTicker);
      const newCoinData = this.state.coinData.map( function({ticker, name, balance, price}) {
        let newPrice = price;
        if ( valueChangeTicker === ticker) {
          const randomPercentage = 0.995 + Math.random() * 0.01;
          newPrice= newPrice * randomPercentage;
        }
        return{
          ticker, //or ticker: ticker
          name,   //or name: name
          balance,
          price: newPrice 
        }
      });

      this.setState({coinData: newCoinData});
    }

    toggleBalance(valueChangeDisplay) {
      console.log(valueChangeDisplay);
      let newBalanceDisplay = this.state.toggleBalanceDisplay.valueOf();
      if ( newBalanceDisplay === true) {
        newBalanceDisplay = false;
      }
      else {
        newBalanceDisplay = true;
      }

      console.log(newBalanceDisplay);
      this.setState({toggleBalanceDisplay: newBalanceDisplay});
    }

    render() {
      return (
        <div className="App">
          <CoinHeader />
          <div>
            <AccountBalance amount={this.state.balance} 
                            showBalance={this.state.toggleBalanceDisplay}
                            toggleBalance={this.toggleBalance}/>
            <CoinList coinData={this.state.coinData} 
                      handleRefresh={this.handleRefresh} 
                      showCoinBalanceHeader={this.state.toggleBalanceDisplay}/>
          </div>
        </div>
      );
    }
  }

export default App;

CoinList.jsx

import React, { Component } from 'react'
import PropTypes from 'prop-types';
import Coin from '../Coin/Coin';

export default class CoinList extends Component {
    render() {
        let coinBalanceHeader = null;
        if (this.props.showCoinBalanceHeader) {
            coinBalanceHeader = <th>Balance</th>;
        }

        return (
            <table className="coin-table">
            <thead>
              <tr>
                <th>Name</th>
                <th>Ticker</th>
                {coinBalanceHeader}
                <th>Price</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>

              {
                this.props.coinData.map( ({name, ticker, balance, price}) =>
                <Coin key={ticker} 
                      handleRefresh={this.props.handleRefresh} 
                      showCoinBalanceHeader={this.props.showCoinBalanceHeader}
                      name={name} 
                      ticker={ticker} 
                      balance={balance}
                      price={price} />
                )
              }
            </tbody>
          </table>
        )
    }
}

CoinList.propTypes = {
    showCoinBalanceHeader: PropTypes.bool.isRequired
  }

Coin.jsx

import React, { Component } from 'react'
import PropTypes from 'prop-types';
import styled from 'styled-components';

const StyledTd = styled.td `
border: 1px solid #e9ebe4;
width: 25vh;
`

export default class Coin extends Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(event) {
        event.preventDefault();
        this.props.handleRefresh(this.props.ticker);
    }

    render() {
        let coinBalanceContent = null;
        if (this.props.showCoinBalanceHeader) {
            coinBalanceContent = <StyledTd>{this.props.balance}</StyledTd>;
        }
        return (
            <tr>
              <StyledTd>{this.props.name}</StyledTd>
              <StyledTd>{this.props.ticker}</StyledTd>
              {coinBalanceContent}
              <StyledTd>${this.props.price}</StyledTd>
              <StyledTd>
                  <form action="#" method="POST">
                    <button onClick={this.handleClick}>Refresh</button>
                  </form>
              </StyledTd>
            </tr>
          );
    }
}

Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    balance: PropTypes.number.isRequired,
    price: PropTypes.number.isRequired
}

AccountBalance.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Section = styled.section `
    border: 2px solid red;
    font-size: 2rem;
    padding: 1.5rem 0 1.5rem 5 rem;
`

export default class AccountBalance extends Component {
    constructor(props) {
        super(props);
        this.balanceClick = this.balanceClick.bind(this);
    }

    balanceClick(event) {
        event.preventDefault();
        this.props.toggleBalance(this.props.showBalance);
    }

    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance';
        let content = null;
        if (this.props.showBalance) {
            content = <>{this.props.amount}</>;
        }

        return (
            <>
            <h2>
                ACCOUNT BALANCE
            </h2>
            <Section>
                Balance: ${content}
                <form action="#" method="POST">
                <button onClick={this.balanceClick}>{buttonText}</button>
                </form>
            </Section>
            </>
        );
    }
}

AccountBalance.propTypes = {
  amount: PropTypes.number.isRequired
  ,showBalance: PropTypes.bool.isRequired
}
2 Likes
App.js
import CoinList from './components/CoinList/CoinList';
import AccountBalance from './components/AccountBalance/AccountBalance.jsx';
import React from 'react';
import Header from './components/Header/Header';
import styled from 'styled-components';

const DIV = styled.div`
text-align: center;
  background-color: rgb(0, 132, 255);
  color: #cccccc;
`;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      balance: 10000,
      showBalance: true,
      coinData: [
        {
          name: 'Bitcoin',
          ticker: 'BTC',
          price: 45000,
          balance: 1
        },
        {
          name: 'Ethereum',
          ticker: 'ETH',
          price: 3000,
          balance: 2500
        },
        {
          name: 'Tether',
          ticker: 'USDT',
          price: 1.0,
          balance: 200000
        },
        {
          name: 'Ripple',
          ticker: 'XRP',
          price: 1.5,
          balance: 0
        },
        {
          name: 'Cardano',
          ticker: 'ADA',
          price: 2.5,
          balance: 10000
        }
      ]
    }
    this.handleRefresh = this.handleRefresh.bind(this);
    this.toggleBalance = this.toggleBalance.bind(this); 
  }

  handleRefresh(valueChangeTicker) {
     const newCoinData = this.state.coinData.map(function ({ticker, name, price}) {
      let newPrice = price;
      if (valueChangeTicker === ticker) {
        const randomPercentage = 0.995 + Math.random() * 0.01;
        newPrice = newPrice * randomPercentage;
      }
      return{
        name,
        ticker,
        price: newPrice
      }

     });
     this.setState({coinData: newCoinData});
  }

  toggleBalance() {
    this.setState({showBalance: !this.state.showBalance});
  }

  render () {
    return (
      <DIV className="App">
        <Header />
        <AccountBalance amount={this.state.balance} showBalance={this.state.showBalance} 
        toggleBalance={this.toggleBalance} />
        <CoinList coinData={this.state.coinData} handleRefresh={this.handleRefresh}
        showBalance={this.state.showBalance}/>
      </DIV>
    );
  }
  
  
}

export default App;

AccountBalance.jsx
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Section = styled.section`
    border: 1px solid white;
    text-align: left;
    padding: 1.5rem 0 1.5rem 3rem;
    font-size: 1.5rem;
`;

export default class AccountBalance extends Component {
    constructor (props) {
        super (props)
    }


    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance';
        const balanceValue = this.props.showBalance ? `Balance: ${this.props.amount}` : null;
        return (
            
            <Section className="amount">
                <button onClick={this.props.toggleBalance}>{buttonText}</button>
                <div>{balanceValue}</div>           
            </Section>
            
            
        );
    }
}



AccountBalance.propTypes = {
    amount: PropTypes.number.isRequired,
    showBalance: PropTypes.bool.isRequired

}

CoinList.jsx
import React, { Component } from 'react'
import Coin from '../Coin/Coin';
import styled from 'styled-components';

const Table = styled.table`
margin: 50px auto 50px auto;
display: inline-block;
font-size: 1.4rem;
`;

export default class CoinList extends Component {

    
    render() {
        const balanceHeader = this.props.showBalance ? <th>Balance</th> : null;

        return (
            <Table className="coin-table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Ticker</th>
                    <th>Price</th>
                    {balanceHeader}
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
              {
                this.props.coinData.map(value => 
                <Coin key={value.ticker} 
                    name={value.name} 
                    handleRefresh={this.props.handleRefresh}
                    ticker={value.ticker} 
                    price={value.price}
                    balance={value.balance}
                    showBalance={this.props.showBalance}/>
                )
              }
            </tbody>
        </Table>
        )
    }
}

Coin.jsx
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Td = styled.td`
border: 1px solid #cccccc;
width: 25vh;
`;

export default class Coin extends Component {
    constructor(props) {
        super(props);
        this.handleRefresh = this.handleRefresh.bind(this);
    }
 

    handleRefresh(event) {
        event.preventDefault();
        this.props.handleRefresh(this.props.ticker);
        /*
        const randomPercentage = 0.995 + Math.random() * 0.01;

        this.setState( function(oldState) {
            return {
                price: oldState.price * randomPercentage
            };
        })*/
    }

    render() {
        const balanceRow = this.props.showBalance ? <Td>{this.props.balance}</Td> : null;

        return (
            <tr>
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>${this.props.price}</Td>
                    {balanceRow}
                <Td><button onClick={this.handleRefresh}>Refresh</button></Td>
            </tr>
        );
    }
}

Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired,
    showBalance: PropTypes.bool.isRequired
}
1 Like

app:

 this.state = {
      balance: 10000,
      showBalance: true,
      coinData: [
        {
          name: 'Bitcoin',
          ticker: 'BTC',
          balance: 0.35,
          price: 35721.51,
        },
        {
          name: 'Ethereum',
          ticker: 'ETH',
          balance: 3.759,
          price: 2513.05,
        },
        {
          name: 'Tether',
          ticker: 'USDT',
          balance: 1000.0,
          price: 1.0,
        },
        {
          name: 'Ripple',
          ticker: 'XRP',
          balance: 120.0,
          price: 0.43,
        },
        {
          name: 'Bitcoin Cash',
          ticker: 'BCH',
          balance: 0.0,
          price: 298.99,
        },
      ],
    }
    this.handleRefresh = this.handleRefresh.bind(this)
    this.handleBalanceVisibility = this.handleBalanceVisibility.bind(this)
  }
....
handleBalanceVisibility() {
    this.setState({ showBalance: !this.state.showBalance })
  }
  render() {
    return (
      <Div className="App">
        <Header />
        <AccountBalance
          amount={this.state.balance}
          showBalance={this.state.showBalance}
          handleBalanceVisibility={this.handleBalanceVisibility}
        />
        <CoinList
          coinData={this.state.coinData}
          showBalance={this.state.showBalance}
          handleRefresh={this.handleRefresh}
        />
      </Div>
    )
  }

AccountBalance:

export default class AccountBalance extends Component {
    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance'
        let balance = this.props.showBalance ?
            <span>Account Balance: ${this.props.amount}</span>
            : null;
        
        return (
            <Section>
                {balance}
                <Button onClick={this.props.handleBalanceVisibility}>{buttonText}</Button>
            </Section>
        )
    }
}

CoinList:

render() {
        const balance = this.props.showBalance ?
                        <th>Balance</th> : null;

        return (
            <Table>
                <thead>
                    <tr>
                    <th>Name</th>
                    <th>Ticker</th>
                    <th>Price</th>
                    {balance}
                    <th>Action</th>
                    </tr>
                </thead>
                <tbody>
                    {this.props.coinData.map(({ name, ticker, balance, price }) => (
                        <Coin
                            key={ticker}
                            handleRefresh={this.props.handleRefresh}
                            name={name}
                            ticker={ticker}
                            price={price}
                            showBalance={this.props.showBalance}
                            balance={balance}
                        />
                    ))}
                </tbody>
            </Table>
        )
    }

Coin:

export default class Coin extends Component {
    // this takes the props and adds a state, making it dynamic
    constructor(props) {
        super(props)
        this.handleClick = this.handleClick.bind(this)
    }
    // props come from the parent component: CoinList
    handleClick = (e) => {
        e.preventDefault()
        this.props.handleRefresh(this.props.ticker)
    }
    
    render() {
        const balance = this.props.showBalance ? <Td>{this.props.balance}</Td> : null
        return (
            <tr>
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>${this.props.price}</Td>
                {balance}
                <Td>
                    <form action="#" method="POST">
                        <Button onClick={this.handleClick}>Refresh</Button>
                    </form>
                </Td>
            </tr>
        )
    }
}
1 Like

I was close after using the React Documentation, but I missed some crucial parts. Here is what I missed

showBalance: true,

I had this set to “Hide Balance”

 <AccountBalance amount={this.state.balance} 
          showBalance={this.state.showBalance}  
          handleToggleChange={this.handleToggleChange} />

I did not link showBalance with the state and missed linking the handleToggleChange function

I did create a function to handle the Toggle

 handleToggleChange() {
    this.setState(prevState => ({
        showBalance: !prevState.showBalance  
    }));

I also binded the state

this.handleToggleChange = this.handleToggleChange.bind(this);

I almost got this right but forgot to add props. I added it later

<button onClick={this.props.handleToggleChange}>{buttonText}</button>

My exercise solution: :slight_smile:

App.js
import React from 'react';
import CoinList from './components/CoinList/CoinList';
import AccountBalance from './components/AccountBalance/AccountBalance';
import { v4 as uuidv4 } from 'uuid';
import Header from './components/Header/Header';
import styled from 'styled-components';

const Div = styled.div`
  text-align: center;
  background-color: rgb(221, 243, 255);
`;

class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      balance: 20000,
      showBalance: false,
      coinData: [
        {
          key: uuidv4(),
          name: "Bitcoin",
          ticker: "BTC",
          balance: 0.25,
          price: 63000.99
        },
        {
          key: uuidv4(),
          name: "Ethereum",
          ticker: "ETH",
          balance: 2,

          price: 4600.99
        },
        {
          key: uuidv4(),
          name: "Binance Coin",
          ticker: "BNB",
          balance: 1,
          price: 550.99
        },
        {
          key: uuidv4(),
          name: "Solana",
          ticker: "SOL",
          balance: 1.25,
          price: 240.99
        }
      ]
    }
    this.handleRefresh = this.handleRefresh.bind(this);
    this.toggleBalance = this.toggleBalance.bind(this);
  }


  handleRefresh(valueChangedTicker) {
    const newCoinsData = this.state.coinData.map(function( {ticker, name, price} ) {
      let newPrice = price;
      if(valueChangedTicker === ticker) {
        const randomPercentage = 0.995 + Math.random() * 0.01;
          newPrice = (newPrice * randomPercentage).toFixed(2);
      }
      return {
        ticker,
        name,
        price: newPrice
      }
    }); 
    this.setState({ coinData: newCoinsData });
  }

  toggleBalance() {
    let newShowBalance = this.state.showBalance ? false : true;
    this.setState({ showBalance: newShowBalance });
  }

  render() {
    return (
      <Div>
        <Header />
        <AccountBalance amount={this.state.balance} showBalance={this.state.showBalance} toggleBalance={this.toggleBalance}/>
        <CoinList coinData={this.state.coinData} showBalance={this.state.showBalance} handleRefresh={this.handleRefresh}/>
      </Div>
    );
  }
}

export default App;
Header.jsx
import React, { Component } from 'react';
import logo from "./logo.svg";
import styled from 'styled-components';

const HeaderHTML = styled.header`
    background-color: #282c34;
    min-height: 10vh;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    color: white;
`;
const H1 = styled.h1`
    font-size: 3rem;
`;
const Img = styled.img`
    height: 5rem;
    pointer-events: none;
`;

export default class Header extends Component {
    render() {
        return (
            <HeaderHTML>
            <Img 
              src={logo}
              alt="React Logo"
            />
            <H1>Coin Exchange</H1>
          </HeaderHTML>
        )
    }
}

CoinList.jsx
import React, { Component } from 'react';
import Coin from "../Coin/Coin";
import styled from 'styled-components';

const Table = styled.table`
  margin: 50px auto 50px auto;
  display: inline-block;
  font-size: 1.4rem;
`;

export default class CoinList extends Component {
    render() {
        const renderTableHead = this.props.showBalance ? <th>Balances</th> : null;
        
        return (
            <Table>
            <thead>
              <tr>
                <th>Name</th>
                <th>Ticker</th>
                <th>Price</th>
                {renderTableHead}
                <th>Refresh</th>
              </tr>
            </thead>
            <tbody>
              {
                this.props.coinData.map( ({name, ticker, price, balance}) => 
                  <Coin 
                    key={ticker} 
                    handleRefresh={this.props.handleRefresh}
                    name={name}
                    ticker={ticker}
                    balance={balance}
                    showBalance={this.props.showBalance}
                    price={price}
                  />
                )
              }
            </tbody>
          </Table>
        )
    }
}

Coin.jsx
import React, { Component } from 'react';
import PropTypes from "prop-types";
import styled from 'styled-components';

const Td = styled.td`
    border: 1px solid grey;
    width: 25vh;
`;
const Button = styled.button`
    width: 100%;
    height: 2.75rem;
    background-color: rgb(221, 243, 255);
    border: none;
    font-size: 1.25rem;
    &:hover {
        background-color: rgb(180, 229, 255);
    }
`;



export default class Coin extends Component {
    constructor(props){
        super(props);
        //If we dont bind we dont have access to props:
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(event) {
        event.preventDefault();
        this.props.handleRefresh(this.props.ticker);
    }

    render() {
        const balances = this.props.showBalance ? <Td>{this.props.balance}</Td> : null;

        return (
            <tr>
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>{this.props.price}€</Td>
                {balances}
                <Td>
                    <form action="#" method="POST">
                        <Button onClick={this.handleClick}>Refresh</Button>
                    </form>
                </Td>
            </tr>
        )
    }
}

Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired
}

AccountBalance.jsx
import React, { Component } from 'react';
import PropTypes from "prop-types";
import styled from 'styled-components';

const Section = styled.section`
    margin-top: 4rem;
    font-size: 2rem;
    text-align: center;
`;
const Strong = styled.strong`
    margin-right: 2rem;
`;
const Button = styled.button`
    background-color: rgb(221, 243, 255);
    border: none;
    border-radius: 20px;
    padding: 0.75rem;
    font-size: 1.65rem;
    &:hover {
        background-color: rgb(180, 229, 255);
    }
`;


export default class AccountBalance extends Component {
    render() {
        const buttonText = this.props.showBalance ? "Hide Balances" : "Show Balances"
        const renderBalance = this.props.showBalance ? <span><Strong>Account Balance:</Strong><span>{this.props.amount}€</span></span> : null;

        return (
            <Section>
                {renderBalance}
                <br/>
                <Button onClick={this.props.toggleBalance}>{buttonText}</Button>
            </Section>
        );
    }
}


AccountBalance.propTypes = {
    amount: PropTypes.number.isRequired
}

I have also done some styling on buttons - change clor on hover :slight_smile:


Not pretty, but it works

App
import React from 'react'
import './App.css'
import CoinList from './components/CoinList/CoinList'
import AppHeader from './components/AppHeader/AppHeader'
import AccountBalance from './components/AccountBalance/AccountBalance'
import styled from 'styled-components'

const AppDiv = styled.div`
  text-align: center;
  background-color: rgb(44, 44, 88);
  color: #cccccc;
  `

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      balance: 10000,
      showBalance: false,
      coinData: [
        {
          name: 'Bitcoin',
          ticker: 'BTC',
          balance: 0.5,
          price: 9999.99
        },
        {
          name: 'Ethereum',
          ticker: 'ETH',
          balance: 32.0,
          price: 299.99
        },
        {
          name: 'Tether',
          ticker: 'USDT',
          balance: 0,
          price: 1.0
        },
        {
          name: 'Ripple',
          ticker: 'XRP',
          balance: 1000,
          price: 0.2
        },
        {
          name: 'Bitcoin Cash',
          ticker: 'BCH',
          balance: 0,
          price: 298.99
        }
      ]
    }
    this.handleRefresh = this.handleRefresh.bind(this)
    this.handleShowBalance = this.handleShowBalance.bind(this)
  }

  handleShowBalance(valueChangeShowBalance) {
    this.setState({ showBalance:!valueChangeShowBalance })
    // console.log(!valueChangeShowBalance)
  }

  handleRefresh(valueChangeTicker) {
    const newCoinData = this.state.coinData.map(function( {ticker, name, price} ) {
      let newPrice = price
      if( valueChangeTicker === ticker ) {
        const randomPercentage = 0.995 + Math.random() * 0.01
        newPrice = newPrice * randomPercentage
      }
      return {
        ticker,
        name,
        price: newPrice
      }
    })
    this.setState({ coinData: newCoinData })
  }

  render() {
    return (
      <AppDiv>
        
  
        <AppHeader />
        <AccountBalance 
          amount={this.state.balance} 
          showBalance={this.state.showBalance} 
          handleShowBalance={this.handleShowBalance} />
        <CoinList 
          coinData={this.state.coinData} 
          handleRefresh={this.handleRefresh} 
          showBalance={this.state.showBalance} />
        

      </AppDiv>
    );
  }
}


export default App;
CoinList
import React, { Component } from 'react'
import Coin from '../Coin/Coin'
import styled from 'styled-components'

const CoinTable = styled.table`
    margin: 50px auto 50px auto;
    display: inline-block;
    font-size: 1.4rem;
    `

export default class CoinList extends Component {

    render() {
      const balanceHeader = this.props.showBalance ? <th>Balance</th> : null

        return (
            <CoinTable>
            <thead>
              <tr>
                <th>Name</th>
                <th>Ticker</th>
                <th>Price</th>
                {balanceHeader}
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {
                this.props.coinData.map( ({name, ticker, balance, price}) =>
                <Coin key={ticker} 
                    handleRefresh = {this.props.handleRefresh}
                    showBalance={this.props.showBalance}
                    name={name} 
                    ticker={ticker} 
                    balance={balance}
                    price={price} />
                )
              }
            </tbody>
          </CoinTable>
        )
    }
}

Coin
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

const CoinRow = styled.td`
    border: 1px solid #cccccc;
    width: 25vh;
    `

const CoinRowHidden = styled.td`
border: 1px solid #cccccc;
width: 25vh;
    display: none;
    `

export default class Coin extends Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick(event) {
        event.preventDefault() 
        this.props.handleRefresh(this.props.ticker)
    }

    render() {
        const coinBalance = this.props.showBalance ? <CoinRow>${this.props.balance}</CoinRow> : <CoinRowHidden>${this.props.balance}</CoinRowHidden>
        return (
            <tr>
                <CoinRow>{this.props.name}</CoinRow>
                <CoinRow>{this.props.ticker}</CoinRow>
                <CoinRow>${this.props.price}</CoinRow>
                {coinBalance}
                <CoinRow>
                    <form action="#" method="POST">
                        <button onClick={this.handleClick}>Refresh</button>
                    </form>
                </CoinRow>
            </tr>
        )
    }
}

Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired
}
AccountBalance
import React, { Component } from 'react'
import PropTypes from 'prop-types'
// import './AccountBalance.css'
import styled from 'styled-components'

const AccountBalanceContainer = styled.div`
    display: inline-block;
    justify-content: center;
    padding-left: 1rem;
    padding-right: 1rem;
    margin-left: 3rem;
    margin-right: 3rem;
    margin-top: 1rem;
    border: 1px solid #FFFFFF;
    `

const AccountBalanceText = styled.p`
    font-size: 1.5rem;
    color: #f2f7af;
    `

export default class AccountBalance extends Component {
    constructor(props) {
        super(props)
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick(event) {
        event.preventDefault()
        this.props.handleShowBalance(this.props.showBalance)
    }

    render() {
        const buttonText = this.props.showBalance ? 'Hide Balance' : 'Show Balance'
        const accountBalanceText = this.props.showBalance ? `Account Balance: $${this.props.amount}` : ''
        return (
            <div>
                <AccountBalanceContainer>
                    
                        <AccountBalanceText>
                        {accountBalanceText}
                        <button onClick={this.handleClick}>{buttonText}</button>
                        </AccountBalanceText>
                    
                </AccountBalanceContainer>
            </div>
        )
    }
}

AccountBalance.propTypes = {
    amount: PropTypes.number.isRequired
}