Handy tips for React beginners

Are you learning React? It’s a great library, but not without its nuances, which can be a cause of frustration for beginners. Today we’ll discuss some handy tips that’ll get you past the most common stumbling blocks and on your way to React mastery!

Note:
This post is aimed to compliment your journey into learning React, you’ll still need a good understanding of the library. For that the official React documentation is a good start.


React.Fragment

Love it or hate it, React uses JSX for templating. Under the hood this is compiled to call React.createElement(). As such there are a few specific rules we need to adhere to when writing our JSX.

One of those rules is the maximum number of JSX root nodes allowed in our components render method. We can only return one and it’s a common stumbling block for newcomers.

One method I see a lot is wrapping our nodes in a div, it solves the problem, but isn’t particularly semantic. What if we don’t want extra tags cluttering up our markup? Thankfully the React team have provided a great solution, React.Fragment.

React.Fragment is a React component, it allows us to return multiple root nodes without having to wrap them in an additional DOM element. Best of all React.Fragment is not rendered to the DOM when compiled.

Note:
React.Fragment has a shorthand syntax available, you may see it written as <></>.

Example

render() {
	return (
		<React.Fragment>
			<h1>Some heading</h1>
			<span>Some sub-heading</span>
		</React.Fragment>
	);
}

/*
DOM output:
<h1>Some heading</h1>
<span>Some sub-heading</span>
*/

Learn more:
Official React documentation - React.Fragment


Conditional rendering

If you’re coming from an Angular or Vue background, you’ll be familiar with how those frameworks provide conditional helpers including ngIf and v-if. React, being a library, doesn’t include off-the-shelf helpers. We can easily replicate these helpers using the power of JavaScript and JSX expressions.

We’ll focus on JSX inline conditional rendering, as this is one of the main hurdles that most React beginners face.

Inline if with logical && operator

const UserGreeting = props => {
	const isLoggedIn = props.isLoggedIn;
	return (
		<h1>Welcome
			{isLoggedIn &&
				back
			}
		</h1>
	)
}

Here we’re conditionally checking the property isLoggedIn. If true we output the string back to render Welcome back, if false we skip the output entirely, only rendering Welcome.

Inline if-else with conditional operator

const UserGreeting = props => {
	const isLoggedIn = props.isLoggedIn;
	return (
		<h1>Welcome
			{isLoggedIn ? (
				back
			) : (
				user
			)}
		</h1>
	)
}

Here we’re conditionally checking the property isLoggedIn using a JavaScript conditional operator condition ? true : false. Based on the result we’re either outputting the string back or user.

Let’s see how we can refactor the above example as a single line expression.

const = UserGreeting = props => {
	return (
		<h1>Welcome {props.isLoggedIn ? 'back' : 'user'}</h1>
	)
}

Finally let’s see how we can use this component, note how we pass our Boolean, it’s not wrapped in quotes, doing so would cause it to be evaluated as a string!

...return(
	<UserGreeting
		isLoggedIn={true}
	/>
)

/*
Output:
<h1>Welcome back</h1>
*/

Can you see how with a little refactoring we’ve been able to dramatically reduce the amount of lines written? Obviously this approach should be used sparingly as large expressions can make code review more difficult.

Learn more:
Official React documentation - Conditional rendering


Dynamic element tags

As you begin to use React more, you’ll notice some components require the use of a dynamic element tag. A good example is a title component. To ensure good SEO, we would require the functionality to dynamically set the level of the <h> tag wrapping our title.

How do we provide a solution to this issue, create six independent title components? We could, but it’s not very DRY and it would never get past code review. Instead we should dynamically set our element tag at runtime, based on a passed property.

In React we differentiate DOM tags from Component tags using lower-case or upper-case naming e.g <button> vs <Button>. Therefore it’s important we save our tag name to a variable that starts with an upper-case letter!

Example

const Title = props => {
	
	// Create a variable to store our element tag, note the capital letter!
	const Element = props.headerLevel;
	
	// Use our element variable in our return method
	return (
		<Element>
			{props.children}
		</Element>
	)
}

// Set a default headerLevel prop as a fallback
Title.defaultProps = {
	headerLevel: "h1"
}

See how easy that was? By allowing a dynamic tag to be set as a property and passing this variable into our return method, we were able to create a re-usable and flexible Title component. Note that we’ve set a default headerLevel prop to an h1 using Reacts built in defaultProps property.

Learn more:
Official React documentation - Choosing the element type at runtime
Official React documentation - Default props


Props.children

props.children is available on every component, it contains the content passed between the opening and closing tags of a component. This can be anything from a simple string to another React component, it’s a powerful and useful concept to learn.

Basic example

Let’s refer back to our title component from the last section. We’ll start by creating the component.

const Title = props => {
	
	// Create a variable to store our element tag, note the capital letter!
	const Element = props.headerLevel;
	
	// Use our element variable in our return method
	return (
		<Element>
			{props.children}
		</Element>
	)
}

// Set a default headerLevel prop as a fallback
Title.defaultProps = {
	headerLevel: "h1"
}

Now let’s use that component, see how the text Hello World! is passed as the child.

... return (
	<Title headerLevel="h2">Hello World!</Title>
)

props.children opens up support for more advanced functionality in our components. One common approach is the use of slots. You can think of slots as container areas within our UI.

To help you understand the concept let’s build a simple titleBar component. The component uses flexbox and allows child nodes to be placed in either a left or right container, which will align items flex-start or flex-end (left or right justified).

Let’s start by building the component, note how we wrap each slot in a conditional render. If the prop isn’t passed, the render skips over the slot with no issues.

const TitleBar = props => {
	return (
		<div className="title-bar">
			{props.leftSlot && 
				<div className="left-slot">
					{props.leftSlot}
				</div>
			}
			{props.rightSlot &&
				<div className="right-slot">
					{props.rightSlot}
				</div>
			}
		</div>
	)
}

Now let’s use that component, notice how we’ve passed other React components as properties.

...return(
	<TitleBar
		leftSlot={
			<Title headerLevel="h1">App title</Title>
		}
		rightSlot={
			<AppNavigation/>
		}
	/>
)

As you can see props.children is a powerful concept, you’ll see it used frequently within React projects.

Learn more:
Official React documentation - props.children
Official React documentation - Containment


Dynamic CSS classes

Both Angular and Vue come complete with helpers for dynamic css classes, namely ngClass and v-bind:class. Unfortunately React doesn’t offer any helpers, but with a little JavaScript we can replicate this.

Conditional CSS classes

We’ve already touched on conditional rendering, so you’re already halfway towards solving the problem. Let’s create a simple blog post article container, we can pass it a featuredArticle prop, which will append an additional class featured to the container.

const ArticleContainer = props => {
	return (
		<div className={ props.featuredArticle ? "article-container featured" : "article-container"}>
			{props.children}
		</div>
	)
}

// Set default prop value
ArticleContainer.defaultProps = {
	featuredArticle: false
}

Now let’s use our new component:

...return (
	<ArticleContainer featuredArticle={true}>
		...article content
	</ArticleContainer>
)

So we’ve now learnt how to execute conditional class names, but have you noticed how we’re repeating our default article-container class name? We can do better than that by leveraging ES6 template literals. Let’s refactor!

const ArticleContainer = props => {
	return (
		<div className={ `article-container ${props.featuredArticle ? "featured" : ""}` }>
			{props.children}
		</div>
	)
}

// Set default prop value
ArticleContainer.defaultProps = {
	featuredArticle: false
}

We’ve now provided our default class name article-container and interpolated the result of our conditional operator, outputting featured if true, or and empty string if false.

Learn more:
Official React documentation - Styling and CSS
NPM classnames package


Conclusion

Today we’ve covered some great concepts that will strengthen your React development skills. As with all tutorials, you should practice these examples to gain more understanding and context on how they could be used within your own project.

That’s all folks, thanks for reading.