Finally bullish on React🤣
Solution:
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';
import axios from 'axios';
const Div = styled.div`
text-align: center;
background-color: rgb(0, 65, 139);
color: #cccccc;
`;
const COIN_COUNT = 10;
const formatPrice = price => parseFloat(Number(price).toFixed(4));
class App extends React.Component{
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: 297.99
},
*/
componentDidMount = async () => {
const response = await axios.get('https://api.coinpaprika.com/v1/coins');
const coinIds = response.data.slice(0, COIN_COUNT).map(coin => coin.id);
const tickerUrl = 'https://api.coinpaprika.com/v1/tickers/';
const promises = coinIds.map(id => axios.get(tickerUrl + id));
const coinData = await Promise.all(promises);
const coinPriceData = coinData.map(response => {
const coin = response.data;
return {
key: coin.id,
name: coin.name,
ticker: coin.symbol,
balance: 0,
price: formatPrice(coin.quotes.price),
};
});
// Retrieve the prices
this.setState({ coinData: coinPriceData });
}
handleBalanceVisibilityChange = () => {
this.setState( function(oldState) {
return {
...oldState,
showBalance: !oldState.showBalance,
}
});
}
handleRefresh = async (valueChangeId) => {
const tickerUrl = `https://api.coinpaprika.com/v1/tickers/${valueChangeId}`;
const response = await axios.get(tickerUrl);
const newPrice = formatPrice(response.data.quotes.USD.price);
const newCoinData = this.state.coinData.map( function( values ) {
let newValues = { ...values };
if ( valueChangeId === values.key ) {
newValues.price = newPrice;
}
return newValues;
});
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;
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( ({key, name, ticker, balance, price}) =>
<Coin key={key}
handleRefresh={this.props.handleRefresh}
name={name}
ticker={ticker}
balance={balance}
showBalance={this.props.showBalance}
price={price}
tickerId={key} />
)
}
</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 black;
width; 25vh;
`;
export default class Coin extends Component {
handleClick = (event) => {
//Prevent the default action of submitting the form
event.preventDefault();
this.props.handleRefresh(this.props.tickerId);
}
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,
}