...

/

Stateful Components

Stateful Components

Learn how to manage state using React with the help of an example.

We'll cover the following...

In the previous lesson, we saw how to build a stateless React component. By stateless, we mean that the component only receives input from the outside and it doesn’t need to calculate or manage any internal information to be able to render itself to the DOM.

While it’s great to have stateless components, sometimes, we have to manage some kind of state and React allows us to do that. So, let’s learn how with an example.

A simple React application

Let’s build a React application that displays a list of projects that have been recently updated on GitHub.

We can encapsulate all the logic for asynchronously fetching the data from GitHub and displaying it on a dedicated component: the RecentGithubProjects component. This component is configurable through the query prop, which allows us to filter the projects on GitHub. The query prop will receive a keyword such as the “javascript” or “react” keywords, and this value will be used to construct the API call to GitHub.

Let’s finally take a look at the code of the RecentGithubProjects component.

Press + to interact
import react from 'react'
import htm from 'htm'
const html = htm.bind(react.createElement)
function createRequestUri (query) {
return `https://api.github.com/search/repositories?q=${
encodeURIComponent(query)
}&sort=updated`
}
export class RecentGithubProjects extends react.Component {
constructor (props) { // (1)
super(props) // (2)
this.state = { // (3)
loading: true,
projects: []
}
}
async loadData () { // (4)
this.setState({ loading: true, projects: [] })
const response = await fetch(
createRequestUri(this.props.query),
{ mode: 'cors' }
)
const responseBody = await response.json()
this.setState({
projects: responseBody.items,
loading: false
})
}
componentDidMount () { // (5)
this.loadData()
}
componentDidUpdate (prevProps) { // (6)
if (this.props.query !== prevProps.query) {
this.loadData()
}
}
render () { // (7)
if (this.state.loading) {
return 'Loading ...'
}
// (8)
return html`<ul>
${this.state.projects.map(project => html`
<li key=${project.id}>
<a href=${project.html_url}>${project.full_name}</a>:
${' '}${project.description}
</li>
`)}
</ul>`
}
}

There are some new React concepts in this component, so let’s discuss the main details here:  ...