Header component exercise

Welcome,

Here you can post and discuss your solutions to the header component exercise.

Not fully convinced I like styled components yet. If you have a lot of styles all the CSS will clutter the component file. Though if that’s the case it might be a hint you need to refactor into multiple components anyway.

App

Since you can name the styled components whatever your want I called it Content instead of div.

const Content = styled.div`
  text-align: center;
  background-color: rgb(20, 56, 97);
  color: #cccccc
`;

class App extends React.Component {

// constructor same as before

  render() {
    return (
      <Content>
        <AppHeader />
        <AccountBalance amount={this.state.balance} />
        <CoinList coinData={this.state.coinData} />
      </Content>
    );
  }
}
AppHeader

Moved all the styles into styled components and removed App.css.
EDIT: forgot to remove the classes as they are now redundant.

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


const Header = styled.header`
  background-color: #282c34;
  min-height: 20vh;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  font-size: 36px;
  color: white;
`;

const Img = styled.img`
    height: 8rem;
    pointer-events: none;
`;

const H1 = styled.h1`
    font-size: 4rem;
`;

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

//App.js
import React from ‘react’;
import CoinList from ‘./components/CoinList/CoinList’;
import AccountBalance from ‘./components/AccountBalance/AccountBalance’;
import Header from ‘./components/Header/Header’;
import styled from ‘styled-components’

const Div= styled.divtext-align: center; background-color: #61dafb; color: white;;

<Div >
  <Header />   
  <AccountBalance amount={this.state.balance}/>
  <CoinList        coinData={this.state.coinData}/>                      
</Div>

//Header.jsx
import React, { Component } from ‘react’;
import logo from ‘…/…/logo.svg’;
import styled from ‘styled-components’

const Img= styled.imgheight: 8rem; pointer-events: none; ;
const AppHeader= styled.header background-color: #282c34; min-height: 20vh; display: flex; flex-direction: row; align-items: center; justify-content: center; color: white; ;

const H1= styled.h1 font-size: 4rem; ;

        <AppHeader>
        <Img src={logo}  alt="logo" />
          <H1 >
            Coin Exchange
          </H1> 
        </AppHeader>          

//CoinList.jsx
import React, { Component } from ‘react’;
import Coin from ‘…/coin/coin’;
import styled from ‘styled-components’

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

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

You have a point regarding refactoring.

Think about it this way: in 2011, I heard about Bitcoin, didn’t do anything about it, I thought it was another E-Gold that would perish due to governments. In 2014, I heard about React, I thought it violated separation of concerns by placing markup in JavaScript. So I wasn’t an early adopter and waited until 2016 or so, when it was evident that we can’t even hire if we don’t move to React. Now comes styled components… :slight_smile: It has its pros and cons, but if you think about it deeply, it’s not as bad as it looks like at first glance, and solves quite a lot of problems not even Sass or CSS Architecture patterns address.

1 Like

Good call formatting code-responses this way, @mayjer. It’s way more convenient to navigate :slight_smile:

ExchangeHeader
import React, { Component } from 'react';
import styled from 'styled-components';
import logo from '../logo.svg';

const Header = styled.header`
    background-color: #282c34;
    min-height: 20vh;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    font-size: 36px;
    color: white;
`;

const Img = styled.img`
    height: 8rem;
    pointer-events: none;
`;

const H1 = styled.h1`
    font-size: 4rem;
`;
App

i

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

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

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

class App extends React.Component {
  // extraneous constructor data ...
  render() {
    return (
      <Div>
        <ExchangeHeader />
        <AccountBalance amount={this.state.balance} />
        <Table>
          <CoinList coinData={this.state.coinData} />
        </Table>
      </Div>
    );
  }
}
1 Like

Before continuing with the course, create a new Header component and abstract all styling and functionality in your new component.
As an optional exercise, if you prefer using styled components, make sure that all css declarations in App.css are all moved to styled component css declarations.

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


const DivApp = styled.div`
    text-align: center;
    background-color: rgb(20, 56, 97);
    color: #cccccc;
    `;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      balance: 10000,
      coinData: [
        {
          name: "Bitcoin",
          ticker: 'BTC',
          price: 9999.9
        },
        {
          name: "Ethereum",
          ticker: 'ETH',
          price: 274.9
        },
        {
          name: "Tether",
          ticker: 'USDT',
          price: 1
        },
        {
          name: "Ripple",
          ticker: 'XRP',
          price: 0.2
        },
        {
          name: "Bitcoin Cash",
          ticker: 'BCH',
          price: 298.99
        },
        {
          name: "Ethereum",
          ticker: 'ETH',
          price: 274.9
        },
        {
          name: "Ethereum",
          ticker: 'ETH',
          price: 274.9
        }
      ]
    }
  }

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

export default App;```
ExchangeHeader.jsx
import React, { Component } from 'react';
import logo from '../../logo.svg';
import styled from 'styled-components';
const Img = styled.img`
    height: 8rem; /*40vmin;*/
    pointer-events: none;
    `;

const Header = styled.header`
    background-color: #282c34;
    min-height: 20hv;/* 100vh;*/
    display: flex;
    flex-direction: row; /*column;*/
    align-items: center;
    justify-content: flex-start; /*center;*/
    font-size: 36px; /*calc(10px + 2vmin);*/
    color: white;
  `;

const H1 = styled.h1`
    font-size: 4rem;
    `;

export default class ExchangeHeader extends Component {

    render() {
        return (
            <Header>
                <Img src={logo} alt="React logo" />
                <H1>
                    Coin Exchange
                </H1>
            </Header>
        )
    }
}
CoinList.jsx
import React, { Component } from 'react'
import Coin from '../Coins/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>
              </tr>
            </thead>
            <tbody>
              {
                this.props.coinData.map( ({name, ticker, price}) =>
                  <Coin key={ticker} name={name} ticker={ticker} price={price} 
                  />
                )
              }
            </tbody>
          </Table>
        )
    }
}