Styled Components exercise

Solved! moving On!

2 Likes

Thank you, I was driving myself crazy over why it was not working!

1 Like

Divide (the complexity) and conquer (each part).

Most people have trouble with trying to debug everything at once.

3 Likes

Change td to Td and remove className="coin-row" from the tr element.

const Td = styled.td`
    border: 1px solid #cccccc;
    width: 25vh;
`;
return (
            <tr>
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>${this.state.price}</Td>
                <Td>
                    <form action="#" method="POST">
                        <button onClick={this.handleClick}>Refresh</button>
                    </form>
                </Td>
            </tr>
        );
2 Likes

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

const TD = styled.td border: 1px solid #2c2b2b; width : 25vh; ;

const Button = styled.td border: 3px solid blue; background-color: black; color:white; border-radius: 10px; font-size: 18px; text-align: center; width: 150px; ;

…

render() {
return (

{this.props.name}
{this.props.ticker}
${this.getPrice()}

Refresh


)
}

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

const TableData = styled.td`
    border: 1px solid;
    width: 20vh;
    color: dimgray;
`;


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

    handleClick(event){
        event.preventDefault();
        const randomPercentage = 0.995 + Math.random() * 0.01;
        this.setState(function(oldState){
            return{
                price: oldState.price * randomPercentage
            };
        });
    };
    render() {
        return (
            <tr>
                <TableData>{this.props.name}</TableData>
                <TableData>{this.props.ticker}</TableData>
                <TableData>${this.state.price}</TableData>
                <TableData><form action="#" method="POST"><button onClick={this.handleClick}>Refresh</button></form></TableData>
            </tr>
        );
    }
}
Coin.propTypes = {
    name: PropTypes.string.isRequired,
    ticker: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired
}
1 Like
const Th = styled.th `
    border : 1px solid red;
    width : 25vh;
`;
2 Likes
const Td = styled.td`

    border: 1px solid #cccccc;

    width: 25vh;

`;

and change all

<td>

elements to

<Td>

I initially used section and thought that had worked until I changed something and realised the page just hadn’t updated correctly :smile:

Yes, well-formed html is the name of the game. It is always possible to run the W3 html validator on your generated HTML though. For instance, you can open the developer tools, write document.body.outerHTML in the console, then copy-paste the markup in validator.w3.org.

1 Like
import styled from 'styled-components'

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

...

render() {
        return(            
            <tr>            
              <Td>{this.props.name}</Td>
              <Td>{this.props.ticker}</Td>
              <Td>${this.state.price}</Td>
              <Td>
                  <form action="#" method="POST">
                      <button onClick={this.handeClick}>Refresh</button>
                  </form>
                </Td>           
            </tr>
        );
    }
1 Like

image

…

2 Likes

I have problems with my styled component , seems like the code is correct but when i run it , just not styled like the way supposed to be ,please help me to see what ´s wrong here, btw my version package.json is above 5 .

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.state = {

      price: this.props.price

  }

  this.handleClick =this.handleClick.bind(this);

}

handleClick(event){

    event.preventDefault();

         const randomPercentage = 0.995 + Math.random() * 0.01;

         this.setState( function (oldState){

          return {

            price: oldState.price * randomPercentage

          };

         });

    }

         

    render() {

        return(

            <tr> 

                <Td>{this.props.name}</Td>

                <Td>{this.props.ticker}</Td>

                <Td>${this.state.price}</Td>  

                <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

}

APP.JS

import React from 'react';

import logo from './logo.svg';

import './App.css';

import Coin from './Components/Coin/coin';

import AccountBalance from './Components/AccountBalance/AccountBalance';

class App extends React.Component {

    constructor(props) {

      super(props);

      this.state ={

        balance: 10000,

        coinData: [

         {

          name: 'Bitcoin',

          ticker:'BTC',

          price: 9999.99

         },

         {

          name: 'Ethereum',

          ticker:'ETH',

          price: 29.99

         },

         {

          name: 'Tether',

          ticker:'USDT',

          price: 1.0

         },

         {

          name: 'Ripple',

          ticker:'XRP',

          price: 0.2

         },

         {

          name: 'Bitcoin cash',

          ticker:'BCH',

          price: 298.99

        },     

      ]

    }

  }

      

    render() {

      return (

    <div className="App">

      <header className="App-header">

        <img src={logo} alt="React logo" className="App-logo"/>

       <h1 className="App-title">

          Coin Exchange

        </h1>              

      </header>

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

       <table className="coin-table">

        <thead>

         <tr>

           <th>Name</th> 

           <th>Ticker</th>

           <th>Price</th>

         </tr>   

      </thead> 

       <tbody>

         {

           this.state.coinData.map(({ name,ticker,price}) =>

             <Coin key={ticker} name={name} ticker={ticker} price={price}/>

           )

         }

        

       </tbody>

      </table> 

    </div>

  );

}

}

export default App;
1 Like

I added the following to Coin.jsx:

import styled from 'styled-components';
const CoinRow = styled.td`
  border: 1px solid #cccccc;
  width: 25vh;
`;

and changed the body of render() to this:

return (
            <tr>
              <CoinRow>{this.props.name}</CoinRow>
              <CoinRow>{this.props.ticker}</CoinRow>
              <CoinRow>${this.state.price}</CoinRow>
              <CoinRow>
                <form action="#" method="POST">
                  <button onClick = {this.handleClick}>Refresh</button>
                </form>
              </CoinRow>
            </tr>
          );
2 Likes
import React, {component} from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components'

const CoinRow =styled.td'
border:1px solid#ccccccc;
width: 30vh;
color: white;
';

render(){
return(
<tr>
<CoinRow>{this.props.name}</CoinRow>
<CoinRow>{this.props.ticker}</CoinRow>
<CoinRow>{this.state.price}</CoinRow>
<CoinRow>
<form action="#"method="Post">
<button on Click={this.handleClick}>Refresh</button>
</form>
</coinRow>
</tr>
);
}
2 Likes
const Tabledata = styled.td`
    border: 1px solid rgb(15, 10, 10);
    width: 25vh;
`;
   render() {
        return (
            <tr>
              <Tabledata>{this.props.name}</Tabledata>
              <Tabledata>{this.props.ticker}</Tabledata>
              <Tabledata>${this.state.price}</Tabledata>
              <Tabledata>
                <form action='#' method='POST'>
                  <button onClick={this.handleClick}>Refresh
                  </button>
                </form>
              </Tabledata>
            </tr>
        );
      }
2 Likes
const Td = styled.td`
border: 1px solid #cccccc;
width: 25vh;
`;
2 Likes

Inserted styled components at Coins.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;
`;

then changed “td” to “Td”

render() {
        return (
            <tr className="coin-row">
                <Td>{this.props.name}</Td>
                <Td>{this.props.ticker}</Td>
                <Td>${this.state.price}</Td>
                <Td>
                    <form>
                        <button onClick={this.handleClick}>Refresh</button>
                    </form>
                </Td>
            </tr>
        );
    }
2 Likes

Two possible implementations:

  1. We can apply styling to to every element individually:
const CoinCell = styled.td`
display: table-cell;
border: 1px solid;
vertical-align: middle;
`
  1. We can apply styling to all elements in a row:
 const CoinRow = styled.tr`
td {
    display: table-cell;
    border: 1px solid;
    vertical-align: middle;

}
`

Option two seems a bit more parsimonious here, because we don’t have to replace every <td> element with a <CoinCell> element when our table uses uniform styling anyway. On the other hand, styling cells individually might become handy in the future when we update our app and want to, for example, highlight some data in a single cell. Any reason to prefer one over the other @zsolt-nagy?

1 Like

I’d prefer the first one, because most likely, you’d make td a separate React component with additional functionality, unless you click on a row and not on a cell. But if you clicked on a row, then why would you need a table in the first place instead of a simple unordered list? So it’s natural to create React components for each td. As components are self-contained, styles belong to the component itself and not to its container.

This example addresses the table row styling only as I missed that there was styling on the td’s:
const Coinrow = styled.tr`

border: 2px solid #cccccc;

width: 25vh;

`

;

In the render(section):

        <td>{this.props.name}</td>

        <td>{this.props.ticker}</td>

        <td>${this.state.price}</td>

        <td>

            <form action="#" method="POST">

            <button onClick={this.handleClick}>Refresh</button>

            </form>

        </td>

    </Coinrow>
1 Like