Fetching Crypto price with React

Written by krissanawat | Published 2018/12/30
Tech Story Tags: fetching-crypto-price | reactjs | cryptocurrency-react | javascript | react

TLDRvia the TL;DR App

Fetching Crypto Price with React

Before we dive into the code, let’s talk a bit about the project we’re going to do and few requisites.You’ll need the knowledge on:

  1. HTML: Only very basic knowledge.
  2. JavaScript: Intermediate level to write functions (ES6).
  3. CSS: Optional but preferred. We won’t talk about why it looks so and so. That’s where CSS comes to play. You can start with the provided starter template which includes all required CSS.
  4. Familiarity with any API, Node or react will be a great advantage as you follow the tutorial.

Setting Up the tools:

NodeJS: Install from here. LTS version is recommended. We won’t be running any JavaScript for the node, but we need Node to run the react app.

Make sure to verify npm is also installed with it. You can also use yarn, an npm alternative, if you are familiar with it. This tutorial will use npm!

npm -v

node -v

If both commands return a version number, you’re good. The numbers might be different from the ones appearing in the image above.

What are we going to make?It’s easy to use than to explain with words.

Setting up the react App

One complicated thing with React is beginning. It’s incredibly difficult to set it up without knowledge of multiple tools which are usually used by intermediate-expert level JavaScript developers. Facebook came up with a tool that can make this task easy. This package is called create-react-app.

This tool configures environment so that we can get directly to React, without dealing with complex tools. On the better side, it also allows separating the react app from itself so that we can have a complete control over it. That’s a win-win with both set up and control.

**To install the create-react-app globally:**$ npm install -g create-react-app

**To create an app using this package:**$ create-react-app crypto-reactdev

crypto-reactdev is our app name.

I got an error saying ‘create-react-app’ is not recognized. If you get the same error, there are two solutions. Use one of these:

  • Add the node_modules directory to path. The default path is C:\Users\USERNAME\AppData\Roaming\npm\node_modules

  • Or use a slightly different command:npx create-react-app crypto-reactdev

I used the second one.

It’ll create a new directory, crypto-reactdev with required files and folders.

What each file and folders are for?

package.json contains the list of modules that application uses. Each module performs a function or a set of functions.node_modules stores all packages that are listed in package.json.src contains all React source code files.public contains static files such as stylesheets and images.

Now, you've got a working React application. Setting up was easy, wasn’t it?

Open the directory in the terminal, many editors come with the built-in terminal. You may utilize that as well. Following screenshots will be from VS Code, integrated with Git Bash terminal. A single command will start the server:$ npm start

The default port is 3000, it will ask to try 3001 if it’s busy! It’ll also open the URL on web browser.The output on the browser should look like this

It’ll automatically reload when you modify files, thanks to create-react-app.

Into the React

The public directory is accessible and rendered to the browser.

The base file is index.html. It has the following line:

<div id="root"></div>

This is the div where we inject the React. We won’t touch this file at all.In the src directory, have a look at index.js file.

Look at this line:ReactDOM.render(<App />, document.getElementById('root'));

  1. It gets root div from the index.html file.
  2. Injects App component in that div.

You may also use querySelector instead, it’s just used to select this block!

Let’s remove the serviceWorkers as we won’t be using them in this project. Remove the import registerServiceWorker and registerServiceWorker();from index.js. Also remove registerServiceWorker.js file from srcdirectory.

What are all these imports on the top?

In react, every rendered piece is a component.

  • React is required to process JSX. The html-like code you see is not html, it’s JSX.When creating a div, it (babel) transpiles the code to React.createElement().This needs React. You can refer to babel documentation for details regarding babel.

  • import React, { Component } from 'react' imports both React and a method from React called Component. React.Component refers to Component within the React.When we refer Component it refers to Component imported as {Component}. Using Component is my personal preference.Removing {Component} and using React.Component instead does not reduce the import cost. It works exactly same both ways and doesn’t show any difference in performance

  • ReactDOM is used to handle the dom that contains all elements on page. This used to be a part of React once and has been split to a different one. This package provides DOM-specific methods that can be used at the top level of your app.

Let’s get to the main file, src/App.js`

The content you see in the browser comes from this file.Remove everything under return so that it looks something like below.

Did you notice the change on the app running in the browser? Look at the changes.

Please ignore my editor settings injected into code in the screenshot.Size of the import on right of the import statement and ‘edited by You…’ are injected by extensions and are not part of the code.Refer to the actual code on this GitHub repository. Keep an eye on commits, I keep committing frequently on small every change. If you don’t have local setup, you can use it on codesandbox on the web here.

The return statement has a few conditions:

  1. It can return only one element: that could be one div or one p element.
  2. If you’ve to return multiple elements, create a parent div and return the parent div instead.
  3. Return must be included in parenthesis () when multi-line. Parenthesis are optional when returned in a single line.

Since I need multi-line return, I’ll use parenthesis.

The class in html translates to className in JSX because class conflicts with JavaScript class. Classes App and App-header are pre-defined in the App.css file that we imported in the App.js.

There isn’t much styling in this app. Since it is about react, we won’t discuss about CSS. If your app doesn’t look like ours as you follow along you can always replace styles from App.css from the repository. We strongly recommend to start with provided starter files, get them here.

Back to React!

React consists of components that fit together. These components are kept as small as practical.

Let’s break down the react application into components:

  1. Individual crypto currencies.
  2. Parent component to handle data for all individual components.

Keeping the project organized is a better idea so create a directory named components inside src.

Create two files inside components:

Crypto.js and Crypto.css.

Crypto.css

.crypto {
list-style-type: none;
padding: 0;
display: inline-flex;
}

Before jumping into Crypto.js, we must talk about functional components React.There are two ways to define the components in React. We have done one in the App.js using class App extends Components, that kind of components are called pure or stateful components. They look like:

Class ClassName extends Component {
Render () {
Return (
<ComponentName>
Any text or resource!
</ComponentName>
)
}

There is a new modern way of declaring components, these are called stateless components. The stateless functional components give a better performance and are less clunky to write. It’s not the lines of code that is written, which is almost same.

It’s declared like an ES6 function. Stateless functional components are useful for presentational components. That means they can’t use the states, state refers to the object owned by the component where it is declared. It is limited to the current component. It has data that component can keep track of. The state can be initialized or data can be changed on the fly within the component.

Any component that does not use the state should be declared in the stateless fashion. Arrow functions are more compact and offer a concise syntax for writing function expressions.

Const MyComponent = (props) => {
Return (
<Component>
{prop.myProperty}
</Component>
)
}

Save the stateless vs stateful topic for another discussion, let’s continue with the app crypto-reactdev!

Crypto.js

We’re importing React, and Component on the first line. Then we’re importing stylesheet file.

We’re making a class Crypto and exporting it as the default class so that it can be imported at another location to be used with other components.

Create a constructor in the Crypto component so that our data is set when we create an element. We’re using dummy data for setting up the state so idand price are fixed. These values will be obtained from API later. super()needs to be called as Crypto extends a parent class and super calls constructor from a parent class, it is mandatory by JavaScript rules.

Every component must have a function named render. Define render in the Crypto class, outside the constructor.

render () {
return (
           
       )
}

Return will contain whatever the class will return.

Let’s fill up with some code…

render () {
let crypto = this.state.data.map (
(currency) => {
<li key={currency.id}>
<h3>{currency.id} </h3>
<h4>$ {currency.price}</h4>
</li>
})
return (
<div className="crypto-container">
<ul className="crypto">{crypto}</ul>
</div>
)
}

In the render, we map the values. This is the same JavaScript map function, introduced in ES6. The key is defined to keep track of the li we need to update as the price changes. It contains other data such as id and price on the screen.

Curly braces in the React {} refer to the JavaScript code. {crypto} refers to crypto variable.The return statement returns a single crypto component inside a container. className is provided for styling.Now our Crypto component is ready, but the output screen does not change because we have not rendered anything yet.

The rendered Component is App. We import Crypto in App using:import Crypto from './components/Crypto'

Include the <Crypto/> component in App as shown below.

The browser should output something like this.

Adding More Components

Our App is all set for more child components to handle each crypto-currency. This will enable us to use same component with specific features and styles for each one.Inside components folder, use two files Currency.js and Currency.css. I’ve added some CSS to Currency.css, find it here.

Since the Currency.js won’t be using states, we should declare this component as functional (or stateless).

const Currency = props => {return ()}export default Currency

This is how it is declared. It doesn’t need render function.

Before returning, we need the variables set, so get variables from props using object destructuring. All variables required are inside data in the result. I’ll get this from CoinMarketCap API.

Also keep note that declaring this as ES5 function instead of using arrow functions is possible but you might frequently run into binding issues with react. I recommend arrow functions, they are less confusing!

const {
id,
name,
symbol,
price_usd,
percent_change_1h,
percent_change_24h,
percent_change_7d,
} = props.data

We want to return a single currency so return

<li className= {'currency ' + id}><p className="currency-name">{name} ({symbol})</p><h1>${(+price_usd). toFixed (2)} </h1><p>{percent_change_1h} % 1hr</p><p>{percent_change_24h} % 24hrs</p><p>{percent_change_7d} % 7days</p></li>

This return data represents a single currency.Since we need more data fields now, I added the dummy data fields to Crypto.js

This data can be used in Currency component. We must import Currencycomponent in the Crypto.js. We need to render this component instead of li with h3 and h4.

const crypto = this.state.data.map (currency => (<Currency data={currency} key={currency.id} />))

This iterates through all data in the state.

A single object inside data is received as currency in the map function. This is passed as data in the Currency component. We also pass key to keep track of the component.

What do we get?

Excellent output, except for the data.

Getting the data for react components!

There are multiple ways to get data and using a package to help us is probably the least complicated method of achieving this.

I do not expect you to be familiar with react life-cycle methods, you could solely use that too!

I’ll be using the Axios, it is easy to use asynchronous REST API.Axios doesn’t come with create-react-app. We add to our app using:

$ npm install axios –save

Import axios in Crypto.js, that’s where we’ll be fetching data.import axios from 'axios'

Now, we fetch the currency data through API. We create a function in Cryptoclass to achieve this.

fetchCurrencyData = () => {

axios

.get('https://api.coinmarketcap.com/v1/ticker/?limit=10')

    .then(response => {

      const wanted = ['bitcoin', 'ethereum']

      const result = response.data.filter(currency =>

   wanted.includes(currency.id),

  )
  this.setState({data: result})
 }).
  catch(err => console.log(err))

}

The fetchCurrencyData() is the required function. We filter the result data set for Bitcoin and Ethereum only. We also set the state data to the result after obtaining result.

Since the data is modified, react will reflect the changes in the Currencycomponent.

If you check the browser now, you won’t see any changes. This is because we defined function but never called it.We want to call this when the component loads and every minute thereafter.

React has a thing called lifecycle methods, there are some 8 methods. These are like built in functions. We’ll talk about only one here.

We’ll use componentDidMount method. This will execute the code when component is in view.Inside the Crypto component, add this method as:

componentDidMount () {this. fetchCurrencyData ()this.interval = setInterval (() => this. fetchCurrencyData (), 60 *1000)}

This fetches currency data using our previously declared function. It also uses setInterval to run the same every 60 seconds to get new data.

Now, we should get a working Bitcoin and Ethereum and bitcoin ticker.

Cleaning up the react app!

There’s always something that can be corrected, here’s what we can clean up in this project.Check the console in the browser and remove the unused components.

Remove logo import from App.js, and {Component} from Currency.js

Expanding the currencies

We have Bitcoin and Ethereum tickers, we can expand it to more currencies.

We’re using the REST API URL from this location to get the data. You can see the available ids. We have bitcoin, ethereum, ripple, bitcoin-cash, eos, litecoin, stellar, cardano, iota, tron in order.

Add some of these to the wanted list in Crypto.js.

Here’s my output

The data should automatically refresh.

If it does not update, wait for a while. CoinMarketCap updates the data every 5 minutes and we fetch data every minute. It might take up to 6 minutes to get new data.

Closing Notes:

If this post was helpful, please click the clap 👏 button below a few times to show your support! ⬇⬇


Published by HackerNoon on 2018/12/30