React Redux for Beginners(part_5)

part1 & part2 & part3 & part4

Sanje Qi
4 min readOct 13, 2019

Check part1 to part4 before you read this. This will help you have a better picture.

Intro: A particularly interesting concept is using CSS in JS to abstract CSS to the component level itself, using JavaScript to describe styles in a declarative and maintainable way. With the release of the popular styled-components project by Max Stoiber, this concept is more mainstream today than ever (see below).

So what’s the difference between CSS-in-JS and Inline styles? let’s take it to the ground level. Here’s a simple explanation that makes things clearer at the most down-to-earth level possible: CSS-in-JS attaches a <style> tag on top of the DOM while inline styles just attaches the properties to the DOM node.

In React, CSS-in-JS lets you think and design styles in abstraction in the component level, leveraging the principles of modularity and isolation, unit-testing, DRY principle and so on. It’s a mind-bender, but often a practical one.

Note that the official React docs still state that “React does not have an opinion about how styles are defined; if in doubt, a good starting point is to define your styles in a separate *.css file as usual and refer to them using className.”

SIMPLE STYLING FOR REACT COMPONENTS

The application looks a bit dull without any styling. Therefore you can drop in some of your own styling or use the styling that’s provided in this section.

First, the application would need some application-wide style that can be defined in the src/index.css file:

body {color: #222;background: #f4f4f4;font: 400 14px CoreSans, Arial,sans-serif;}a {color: #222;}a:hover {text-decoration: underline;}ul, li {list-style: none;padding: 0;margin: 0;}input {padding: 10px;border-radius: 5px;outline: none;margin-right: 10px;border: 1px solid #dddddd;}button {padding: 10px;border-radius: 5px;border: 1px solid #dddddd;background: transparent;color: #808080;cursor: pointer;}button:hover {color: #222;}.button-inline {border-width: 0;background: transparent;color: inherit;text-align: inherit;-webkit-font-smoothing: inherit;padding: 0;font-size: inherit;cursor: pointer;}.button-active {border-radius: 0;border-bottom: 1px solid #38BB6C;}*:focus {outline: none;}

Second, the App component defines a few CSS classes in its src/components/App.css file:

.app {margin: 20px;}.interactions, .error {text-align: center;}

Third, the Stories component defines style in its src/components/Stories.css file:

.stories {margin: 20px 0;}.stories-header {display: flex;line-height: 24px;font-size: 16px;padding: 0 10px;justify-content: space-between;}.stories-header > span {overflow: hidden;text-overflow: ellipsis;padding: 0 5px;}

And last but not least, the Story component defines a style in its src/components/Story.css file too:

.story {display: flex;line-height: 24px;white-space: nowrap;margin: 10px 0;padding: 10px;background: #ffffff;border: 1px solid #e3e3e3;}.story > span {overflow: hidden;text-overflow: ellipsis;padding: 0 5px;}

When you start your application again, it seems more organized by its styling. But there is still something missing for displaying the stories properly. The columns for each story should be aligned and perhaps there should be a heading for each column.

First, you can define an object to describe the columns in the src/components/Stories.js file:

import React from 'react';import './Stories.css';import Story from './Story';const COLUMNS = {title: {label: 'Title',width: '40%',},author: {label: 'Author',width: '30%',},comments: {label: 'Comments',width: '10%',},points: {label: 'Points',width: '10%',},archive: {width: '10%',},};const Stories = ({ stories }) =>...

The last column with the archive property name will not be used yet, but will be used in a later point in time of this tutorial. Second, you can pass this object to your Story component in the src/components/Stories.js file. Still the Stories component has access to the object to use it later on for its own column headings.

const Stories = ({ stories }) =><div className="stories">{(stories || []).map(story =><Storykey={story.objectID}story={story}columns={COLUMNS}/>)}</div>

The Story component in the src/components/Story.js file can use the columns object to style each displaying property of a story. It uses inline style to define the width of each column which comes from the object.

const Story = ({ story, columns }) => {...return (<div className="story"><span style={{ width: columns.title.width }}><a href={url}>{title}</a></span><span style={{ width: columns.author.width }}>{author}</span><span style={{ width: columns.comments.width }}>{num_comments}</span><span style={{ width: columns.points.width }}>{points}</span><span style={{ width: columns.archive.width }}></span></div>);}

Last but not least, you can use the COLUMNS object to give your Stories component matching header columns as well. That's why the COLUMNS object got defined in the Stories component in the first place. Now, rather than doing it manually, as in the Story component, you will map over the object dynamically to render the header columns. Since it is an object, you have to turn it into an array of the property names, and then access the object by its keys to retrieve its properties (width, label).

const Stories = ({ stories }) =><div className="stories"><div className="stories-header">{Object.keys(COLUMNS).map(key =><spankey={key}style={{ width: COLUMNS[key].width }}>{COLUMNS[key].label}</span>)}</div>{(stories || []).map(story =><Storykey={story.objectID}story={story}columns={COLUMNS}/>)}</div>

You can extract the header columns as its own StoriesHeader component to keep your components well arranged and separated by concerns.

const Stories = ({ stories }) =><div className="stories"><StoriesHeader columns={COLUMNS} />{(stories || []).map(story =>...)}</div>const StoriesHeader = ({ columns }) =><div className="stories-header">{Object.keys(columns).map(key =><spankey={key}style={{ width: columns[key].width }}>{columns[key].label}</span>)}</div>

In this section, you have applied styling for your application and components. It should be in a representable state from a developer’s point of view. Part 6 next week. Thank you

Source: StackOverflow, Robin Wieruch, Medium, ReactJs, MDN, bitsrc

--

--