Introduction About React Material Design
Developed by Google in 2014, material design is a design language that is very popular for web and mobile applications. It has been inspired by the textures of the physical world, including how lights are reflected and shadows cast. Material surfaces reimagine the mediums of paper and ink. With the use of the Material-UI-Library, it is very easy to make use of the material design elements in the react web or mobile application.
The library’s website can be found at https://material-ui.com.
Setting up the React Material Project:
The first step is to set up a new react project and this can be done by using the create-react-app script in the following way:
$ npx create-react-app react-material-ui
By using the npx command, installation, we are able to execute create-react-app without the need to download and install it first.
After executing this command, a new project directory is available. This is called the react-material-ui.
Change into the new project folder that you created, and you will find the React starter project.
Installing Material-UI Library and Dependencies
The next step is to install more dependencies by using the following command, this ensures that the Material-UI-Library is installed.
$ npm install @material-ui/core
After this, we need to install the Contentful JavaScript library in order to be able to access the Contentful backed:
$ npm install contentful
We now need to ensure that everything is working perfectly, and we do this by starting the development web server with the command:
$ npm start
The browser now opens up and the start page of the default React application is loaded. You should now be able to see the following output in the browser: We are now completely ready to start the implementation of the sample application.
Implementing the Sample Application
Deleting the Default Content:
The first thing that we need to do is delete some parts that belong to the default content implementation.
– First open the file src/App.js and apply the following. Changes
– Delete the JSX code which is available inside the return statement
– Delete the import statement which is importing from ./logo.svg. You can also delete the file as it is no longer needed by us.
Now we can add our own code to the project.
Implementing the Navigation Bar Component:
In order to add a navigation bar, we need to add the code required to display the navigation bar. This code can be displayed by using the Material Design components from the Material-UI library and is added to another component.
To implement the new component, create a new subfolder component in directory src and add a new file NavBar.js.
Insert the code given below in the newly created file:
import React from ‘react’
import AppBar from ‘@material-ui/core/AppBar’
import Toolbar from ‘@material-ui/core/Toolbar’
import Typography from ‘@material-ui/core/Typography’const NavBar = () => {
return(
<div>
<AppBar position=”static”>
<Toolbar>
<Typography variant=”title” color=”inherit”>
React & Material-UI Sample Application
</Typography>
</Toolbar>
</AppBar>
</div>
)
}export default NavBar;
Here, we use the AppBar, Toolbar and typography component from the Material-UI library to output the navigation bar as shown before.
To be able to include the NavBar in our main application component App, we need to make sure that NavBar is exported.
We are now ready to import NavBar in src/App.js:
import React, { Component } from ‘react’
import NavBar from ‘./components/NavBar’class App extends Component {
render() {
return (
<div>
<NavBar />
</div>
)
}
}export default App
The <NavBar /> tag is inserted into the JSX code so that the navigation bar will be part of the output.
Implementing CourseList Component:
We are now adding another component to our application called the CourseList.
We need to add a new file named CourseList.js inside the src/components folder and insert the following code:
import React, { Component } from ‘react’
import Grid from ‘@material-ui/core/Grid’;
import TextField from ‘@material-ui/core/TextField’;
import * as contentful from ‘contentful’import Course from ‘../components/Course’const SPACE_ID = ‘[INSERT CONTENTFUL SPACE ID]’
const ACCESS_TOKEN = ‘[INSERT CONTENTFUL ACCESS TOKEN]’const client = contentful.createClient({
space: SPACE_ID,
accessToken: ACCESS_TOKEN
})class CoursesList extends Component { state = {
courses: [],
searchString: ”
} constructor() {
super()
this.getCourses()
} getCourses = () => {
client.getEntries({
content_type: ‘course’,
query: this.state.searchString
})
.then((response) => {
this.setState({courses: response.items})
console.log(this.state.courses)
})
.catch((error) => {
console.log(“Error occurred while fetching Entries”)
console.error(error)
})
} onSearchInputChange = (event) => {
console.log(“Search changed …” + event.target.value)
if (event.target.value) {
this.setState({searchString: event.target.value})
} else {
this.setState({searchString: ”})
}
this.getCourses()
} render() {
return (
<div>
{ this.state.courses ? (
<div>
<TextField style={{padding: 24}}
id=”searchInput”
placeholder=”Search for Courses”
margin=”normal”
onChange={this.onSearchInputChange}
/>
<Grid container spacing={24} style={{padding: 24}}>
{ this.state.courses.map(currentCourse => (
<Grid item xs={12} sm={6} lg={4} xl={3}>
<Course course={currentCourse} />
</Grid>
))}
</Grid>
</div>
) : “No courses found” }
</div>
)
}
}export default CoursesList;
This component is responsible for the retrieval of course data from the Contentful back-end service and displaying the list of courses to the user.
The first connection to Contentful is established by using the Contentful JavaScript library.
In order to establish this connection, you need to log in to the Contentful back-end (https://be.contentful.com/login), create a new space, insert a Course model like you can see in the following screenshot, and access Space ID and Access Token from the Space settings — API Keys.
To access both values, you need to create a new key by clicking on button Create API Key.
Both the values of the Space ID and Access Token need to be copied and inserted into the string which is assigned to SPACE_ID and ACCESS_TOKEN constants.
Use the following lines of code:
const client = contentful.createClient({
space: SPACE_ID,
accessToken: ACCESS_TOKEN
})
The connection is stored in client. In order to retrieve the list of courses from this connection the method getCourses is added to the component class:
getCourses = () => {
client.getEntries({
content_type: ‘course’,
query: this.state.searchString
})
.then((response) => {
this.setState({courses: response.items})
console.log(this.state.courses)
})
.catch((error) => {
console.log(“Error occurred while fetching Entries”)
console.error(error)
})
}
The client.getEntires method help request to retrieve the list of courses from Contentful. This configuration object requires two properties:
– Content_type
– Query
As the call of getEntries is an asynchronous operation, it returns a promise, enabling us to connect to the result by using then. Inside the then method the list of courses is available in response.items. Those items are stored inside the courses property of the component’s state.
The component’s output is defined by the JSX code which is returned by the rendermethod:
render() {
return (
<div>
{ this.state.courses ? (
<div>
<TextField style={{padding: 24}}
id=”searchInput”
placeholder=”Search for Courses”
margin=”normal”
onChange={this.onSearchInputChange}
/>
<Grid container spacing={24} style={{padding: 24}}>
{ this.state.courses.map(currentCourse => (
<Grid item xs={12} sm={6} lg={4} xl={3}>
<Course course={currentCourse} />
</Grid>
))}
</Grid>
</div>
) : “No courses found” }
</div>
)
}
Here we’re making use of two Material-UI components: TextField and Grid. Both components are added to the output only if course items are available in this.state.courses. In this case, the user is able to use the TextField to initiate a free text search. If the value of the text field changes the method onSearchInputChange is called and the searchString property of the state object is updated with that new value.
The Material-UI Grid component is used to display the courses in a grid layout that is responsive to the screen size. The output for a specific course is generated by the custom Course component which is implemented in the next step. The current course is handed over to this component via the course parameter.
Again we need to import and add CourseList component in App.js:
import React, { Component } from ‘react’
import NavBar from ‘./components/NavBar’
import CoursesList from ‘./components/CoursesList’class App extends Component {
render() {
return (
<div>
<NavBar />
<CoursesList />
</div>
)
}
}export default App
Implementing Course Component-
The last step is to implement the course component.
To do this, create a new file Course.js in folder src/components and insert the below code:
import React from ‘react’
import Card from ‘@material-ui/core/Card’
import CardActions from ‘@material-ui/core/CardActions’
import CardContent from ‘@material-ui/core/CardContent’
import CardMedia from ‘@material-ui/core/CardMedia’
import Button from ‘@material-ui/core/Button’
import Typography from ‘@material-ui/core/Typography’const Course = (props) => {
console.log(props)
return(
<div>
{ props.course ? (
<Card >
<CardMedia style={{height: 0, paddingTop: ‘56.25%’}}
image={props.course.fields.courseImage.fields.file.url}
title={props.course.fields.title}
/>
<CardContent>
<Typography gutterBottom variant=”headline” component=”h2″>
{props.course.fields.title}
</Typography>
<Typography component=”p”>
{props.course.fields.description}
</Typography>
</CardContent>
<CardActions>
<Button size=”small” color=”primary” href={props.course.fields.url} target=”_blank”>
Go To Course
</Button>
</CardActions>
</Card>
) : null}
</div>
)
}export default Course
This is how we complete implementation.
Conclusion:
Material-UI helps us enhance the output of the react application and help implement real-world samples in applications from scratch.