March 19, 2019
Hooks are probably the most talked about feature in the react community in recent times. They made their way into react 16.8. So I thought it would be fun to learn and write something a bit non-trivial with them, for instance fetching data from a server API and displaying them.
But what are hooks? They are just special functions which let you use react features.
// Traditional class approach
import React, { Component } from "react";
import axios from "axios";
class App extends Component {
state = {
flights: null,
error: null
};
componentDidMount() {
axios
.get("https://api.spacexdata.com/v2/launches")
.then(response => {
this.setState({ flights: response.data });
})
.catch(error => {
// Not to be done in production ...
console.log(error)
});
}
renderList = flight => (
<li key={flight.flight_number}>
<p>Flight Number: {flight.flight_number}</p>
<p>Mission name: {flight.mission_name}</p>
</li>
);
render() {
const { flights, error } = this.state;
if (error) {
return <div> Error! </div>;
}
if (!flights) {
return <div> Fetching... </div>;
}
return <ul>{flights.map(flight => this.renderList(flight))}</ul>;
}
}
export default App;
In the traditional approach, you would use a class, and define the state inside it, and use life cycle methods to fetch data. Hence, classes were the preferred way to make components which fetch data, as you could store them in as a state variable.
However using hooks, we can write functional components which can fetch, and load data, without using any life cycle methods (Bye Bye componentDidMount …). Let’s start the refactoring.
const App = () => {}
import React, { useState, useEffect } from "react";
components stateless anymore!)
is a function, which can be used to change it. Let’s define an initial state, and invoke useState with the initial state passed as an argument.
const initState = { flights: null };
const [data, setFlights] = useState(initState);
a function, and a value which react checks, before running the effect again (important to have a value for this, else you will have an infinite render). We can make the ajax call inside the function.
useEffect(
() => {
axios
.get("https://api.spacexdata.com/v2/launches")
.then(response => {
setFlights({ flights: response.data });
})
.catch(error => {
console.log(error);
});
},
[initState]
);
the state.
setFlights({ flights: response.data });
// Trying react hooks
import React, { useState, useEffect } from "react";
import axios from "axios";
import "./App.css";
const App = () => {
const initState = { flights: null };
const [data, setFlights] = useState(initState);
useEffect(
() => {
axios
.get("https://api.spacexdata.com/v2/launches")
.then(response => {
setFlights({ flights: response.data });
})
.catch(error => {
console.log(error);
});
},
[initState]
);
if (!data.flights) {
return <div> Fetching... </div>;
}
return <ul>{data.flights.map(flight => renderList(flight))}</ul>;
};
const renderList = flight => (
<li key={flight.flight_number}>
<p>Flight Number: {flight.flight_number}</p>
<p>Mission name: {flight.mission_name}</p>
</li>
);
export default App;
Welcome to the personal blog of Ankit D Mohapatra.
I am the CTO of Trias Technology Group.
Follow me on twitter