Jump to content
Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Sign in to follow this  
Rss Bot

Create a dashboard app with React

Recommended Posts

When creating a web application with React  – a JavaScript library for building user interfaces – component creation is a significant bonus when updating the page over something like jQuery. The ability to create self-contained, reusable components means you can keep code smaller and more organised. If components are set up well enough, they can be dropped in where necessary with no additional setup required at all.

In this tutorial, we will be making a dashboard application that keeps an eye on important support metrics. The screen is split up into a grid, which can be customised to show different visuals depending on the data it needs to show.

By making a generic widget component we can chop and change the display without affecting any of the underlying code. Wrapping these in a container component allows us to control the source of that data separate from its display.

We will be making use of CSS Grids to display content in defined blocks. Browsers that do not support it will display in a single column, much like when using a smaller screen.

Download the files for this tutorial here.

01. Download the dependencies

After getting the project files, we need to pull down all the required packages we need for the project. These include files from 'create-react-app', which deals with the build process for us.

We also need to run two servers – one that provides hot reloading for the page and another that provides some fake data to test with.

Enter the following on the command line while inside the project directory:

/* in one window */
> yarn install
> yarn start

/* in another window */
> yarn serve

02. Add the first widget

6CtwfjLjKrPwxRPjPtjMda.jpg

Start off with a simple component

To start things off, we will render a simple component on the page. With Babel set up, we can write components using ES2015 classes. All we need to do is import them when we need to and Babel with Webpack will do the rest.

Open up /src/components/App.js and add the import to the top of the page. Then, inside the render function, place the component inside the container <div>.

03. Style a widget box

XwaHMAnT64YKNpZSUFdMfa.jpg

When importing CSS with Webpack, styles can be scoped to just the component in question to avoid them leaking to other parts of the page

On this project, Webpack is set up to pick up CSS imports. This means we can import CSS files like we did with JavaScript in the previous step, which allows us to create separate files for each component. Add the following import to the top of Widget.js. This will link up with the 'Widget' className and will scope the styles to that component.

04. Add heading and content

Each widget will need a short description of what data it is showing. To keep things customisable, we will pass this in as a property – or "prop" – to the component when we use it.

As for the content, React supplies a special 'children' prop, which will contain the content entered between a component's opening and closing tags.

Replace the placeholder <p> in the render function with the following. The Loading component will come into play later on.

05. Let the widget span the grid

rUx5DwQTuEAJFnXB7B8Mda.jpg

With the CSS Grid specification, layout elements such as gutters will be applied regardless of any styling applied to child elements

In addition to the stylesheets we import, we can also create React styles dynamically based on the props passed through.

To span columns and rows with CSS Grid use the grid-column and grid-row properties. We can pass through 'colspan' and 'rowspan' props to alter this per component in a similar way to how table cells work in HTML.

Apply styles in the Widget constructor and link them to the container <div>.

06. Supply default props

Right now our Widget is blank as we do not supply any props as yet. In these cases, we can supply default props to use instead.

Unless told otherwise, CSS Grids will default to taking up the smallest unit it can, which in this case is a 1x1 square. Just before we export the Widget, supply some default props to that effect. 

07. Enforce specific props

RjtmjmEVuqsXjkFMerJCSK.jpg

The NumberDisplay component is a 'presentational' component, as it has no internal state and relies wholly on the props passed to it

Components can provide hints as to what type of values should be sent as props. While developing an application, any incorrectly passed props will show up in the console as warnings to help avoid bugs further down the line.

Just underneath the default props, define what props should or need to be passed in, and what type they should be.

08. Add props to the app

By defining the 'children' prop as required, you may notice the browser complaining it's currently undefined. While this will not break the app, it will keep bugging us until it's sorted.

Head back over to App.js and add a heading prop to the widget we created earlier. Instead of making the tag self-closing, open it up and add some placeholder content to show it's working.

09. Display some data

ZBwiqZvKDsyxarFqmGzJ9e.jpg

We can use the @supports syntax in CSS to detect whether or not the browser supports grid layouts. If not, we default to the single-column view

The NumberDisplay component works much like the widget we just created – it renders some text based purely on the props we pass into it. We can drop it in where we need to and have a consistent display of numerical data.

Import the NumberDisplay component at the top and use it to replace the placeholder content you just added within Widget.

10. Convert to NumberWidget

At the moment, there is quite a lot of code used to show something that will not change across widgets. We can make a special component to encapsulate all of it. That way we only need to import NumberWidget.

Replace the Widget and NumberDisplay imports at the top of App.js with NumberWidget. Make sure to also replace them in the render method.

Next page: Further steps

11. Show a progress bar

Inside NumberWidget.js there are a couple of methods that help us to render things under certain conditions. We can call these in the render method and they can return what we need to output.

Inside showProgress() add some code that works out if we should render a progress bar. We need a minimum, maximum and a value at the very least.

12. Add a Container component

Manually adding data isn't going to be much help to us. We can add a container around NumberWidget that will supply it with fresh data from our server. Inside App.js, replace what we added in step 10 with the NumberWidgetContainer and pass it a URL to load data from.

13. Fetch data on load

Over its lifetime, a React component will call many different methods depending on what point it's at. The componentDidMount method will be called when a component first renders, which makes it an ideal place to fetch data.

Add the following to componentDidMount in NumberWidgetContainer.js. This will call the fetchData method now and every minute after that. We will fix the TypeError in the next step.

14. Update the state

Each component can have its own internal state, which holds information about itself at any given moment. We can pass this state as props for other components to use. 

Make the request to the supplied 'href' prop URL using the AJAX module Axios and update the state with the values supplied. These will automatically be passed to NumberWidget, which will then update itself. 

15. Add in a List widget

The groundwork we have done for NumberWidget can be applied to other types of widgets, too. ListWidgetContainer can be passed the same props as NumberWidgetContainer, but will render a list of values instead.

Import ListWidgetContainer alongside the rest, and place the component just above NumberWidgetContainer in the render method.

16. Display list items

With the data supplied in the sortedItems variable as an array, we can iterate over the results and render a separate component for each.

To do this we can use the 'map' method on the array prototype. This creates a new array of components that React will render.

Inside the ListDisplay component in showWidget, add the map function to create new ListItems.

17. Sort data by value

emSQhuBVHPfbswHnrfcHtm.jpg

Use a sorting function to provide useful information to the user

We should avoid relying on data being sorted at the source to ensure we provide useful information to the user. We can use a sorting function to do this inside the sortListItems method.

Array sorting functions take two values and compare them. Apply this to sortedItems and return it to sort its content in descending order.

18. Add a Graph widget

Graph widgets can display large sets of data clearer than the number or list widgets. It uses a library called Chart.js with a React wrapper that updates as props change. 

Switch back to App.js, import GraphWidgetContainer and add it to the render function under the existing widgets.

19. Prepare data for display

Chart.js takes data in a specific format. In this case, the 'datasets' array is a collection of points used to draw a line.

We will use state to hold all the configuration data for Chart.js and update it with the datasets fetched from the URL, which arrive in a different format.

Open up GraphWidget.js and loop over the props in generateDatasets to update the state.

20. Regenerate when props change

The React wrapper for Chart.js will update when its props change, but as the state holds the set up, we do not update those values directly.

componentWillReceiveProps is another lifecycle method that will fire when a component's props will update. Sometimes this can fire when values have not changed, but a quick check for that can protect against unnecessary updates.

21. Add remaining widgets

Finally, all that is left to do is add in some more data. With the flexibility we have created from the various widgets, we can add in whichever widgets are necessary.

Fill in the remaining gaps on the page. Play around with the types, row and column spans, and positions of widgets to suit the data best.

This article originally appeared in Web Designer issue 262; buy it here!

Related articles:

View the full article

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×