My First Full Stack Web Application
By: Anne-Laure Chadeyras
Tags: Redux Thunk, Programming, Redux, Web Development, React

On the type of component

The technical requirements for this specific projects were to have at least 2 container components and 5 stateless components. A component in React is a building block of the interface. It can receive input from a parent component — referred to as props — and can be re-used as many times as required.

To go into more details about these container components and stateless components, let’s start by explaining in just a few words what state is. State is data that we import and that is subject to change. Amongst the many reasons there is for state to change, two could be: the database it is coming from has been updated, so state will change accordingly or the user modified it.

Container components are also known as stateful components and stateless components are also known as presentational components. The difference between container and presentational components is not strict but rather arbitrary and each developer is free to organise their component as they like. But generally speaking, a container component will have state and will be able to track its changes and a presentational component will not have state, it will either display content that is passed in through props, or always display the same thing.

In the case of the application we are discussing in this article, I decided on a basic split. I built a container component for each model present in my API. As I moved forward, I deleted some that were no necessary and I added others. Mainly, my stateful components are forms. The best examples are the Sign Up form and the Sign In form. In a form in React, for each user input, there is a change in state, whether it is the local state or the Redux store state (we will discuss Redux a little bit later). An example of stateless component would be the list of bicycles found under BicyclesList.js. This component receives as props a list of cities coming from the CitiesContainer component and does not have any connection to state.

Routing in React

Since we built a Single Page Application where no full reload of the page, we could wonder how the routing is done. In a web application Router, you determine what should happen when a user visits a certain page. Since we only have one view in a Single Page Application, we cannot redirect a user to a new view when they click on a link like we used to do in a Rails application.

As always, there is a solution to our problem. Here comes the react-router library. Among other things, it allows us to make sure:

We have a URL displaying what the user is doing, not just the basic root URL

the user is doing, not just the basic root URL A user can use the browser’s forward and back buttons

A user can input a URL into the address bar and navigate to view the page

To explain the pattern I have been using for my routes, I will use the CitiesContainer as an example:

App.js import React from 'react';

import { Route } from 'react-router-dom';

import CitiesContainer from './containers/CitiesContainer'; class CitiesContainer extends React.Component {

render() {

return (

<Route path='/cities' component={CitiesContainer} />

)

}

} export default App;

By using path and not exact path, all paths containing ‘/cities’ would be taken into account. The inside the CitiesContainer component:

containers/CitiesContainer.js import React from 'react';

import { connect } from 'react-redux';

import { Route } from 'react-router-dom';

import { fetchCities } from '../actions/fetchCities';

import CitiesList from '../components/CitiesList';

import CityPage from '../components/CityPage';

import BicyclesList from '../components/BicyclesList'; class CitiesContainer extends React.Component {

componentDidMount() {

this.props.fetchCities()

}



render() {

return (

<div>

<Route exact path='/cities' render={() => <CitiesList

cities={this.props.cities} />} />

<Route exact path='/cities/:id' render={(routerProps) =>

<CityPage {...routerProps} cities={this.props.cities}

/>}/>

<Route path='/cities/:id/bicycles' render={(routerProps) =>

<BicyclesList {...routerProps} cities={this.props.cities}

/>}/>

</div>

)

}

} const mapStateToProps = state => {

return {

cities: state.cities

}

} export default connect(mapStateToProps, { fetchCities })(CitiesContainer)

The routerProps are given to us developers by the react-router-dom package. They allow us to get in props the content of the URL as params. In our case it allows us to get in props the id of the appropriate city, through which we can filter all cities — given by props — and isolate the one we need.