CodePen, ReactJS and MaterializeCSS

So, you want to build a ReactJS App on CodePen, and you want to use the MaterializeCSS framework. How do you do that?

Here’s how.

Getting Started

Pre-requisite: this article assumes you’ve created a simple “Hello World” pen using this article. We’ll be building on what we learned in that post.

HTML Settings

We’re going to include two stylesheets that will give us material icons and also font-awesome icons. The reason for the material icons is because they’re related to Material Design. The reason for the font-awesome icons is because they’re going to be used to provide some social icons, including the free-code-camp icon. Squee.

In the “Stuff for head” section of your HTML Settings, include the following:

  		<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  		<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

CSS Settings

In the CSS settings, change to the SASS pre-processor. It’s my favourite.

You’ll also need to add the Materialize CSS stylesheet in the “Add External CSS” section. The current version that I used at time of writing this article is:

  https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css

JavaScript Settings

In the “Add External JavaScript”, add the following libraries in this order (and after the ReactJS libraries that you’ve already included):

  https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js
  https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js

In The CSS Section

This particular example is following on from the fact that I’m in the middle of doing some freeCodeCamp exercises. Some of the CSS will not be relevant to you at all, but read this bit anyway, because some of it may save you some time getting your head around MaterializeCSS and some SASSy bits.

body
  display: flex
  min-height: 100vh
  flex-direction: column

nav, footer.page-footer
  background-color: darkgreen

nav ul li a, footer.page-footer, footer.page-footer a
  color: #eee

nav .brand-logo
  color: #eee

.brand-logo
  left: 10px

The “body” bit is used to help stabilize the footer. This is necessary if you’re going to include the MaterializeCSS footer.

The nav portions are to control the background-color and the font color. freeCodeCamp uses “darkgreen” as it’s background color, and also “#eee” as its font colors in the header and footer. You can feel free to customize this bit to your heart’s content.

I’ve included the .brand-logo “left” adjustment because I just don’t like how close to the edge the standard framework was placing the logo. That’s all.

In The JavaScript Section

This is where it gets really funky. I’m including some stuff that’s really not necessary and some stuff that kind of is. For me, this is a re-usable template. Feel free to fork it by-the-way.

So, here’s the code:

const Container = ({children}) => {
  return (
<div className="container">{children}</div>
)
}
const Nav = ({children}) => {
  return (
<nav>{children}</nav>

  )
}
const Footer = _ => {
  return (
<footer className="page-footer">
<div className="container">
<div className="row">
<div className="col l6 s12">
<h5>About The Creature</h5>
I'm a JavaScript enthusiast who:
<ul>
	<li>a) teaches JavaScript, CSS and HTML to others</li>
	<li>b) develops Apps and web sites using cool tech</li>
</ul>
</div>
<div className="col l4 offset-l2 s12">
<h5>Ways To Contact Me</h5>
<ul>
	<li><a href="https://twitter.com/RobWelan" target="_blank"><i className="fa fa-twitter" aria-hidden="true"></i> Twitter</a></li>
	<li><a href="https://plus.google.com/u/0/+RobWelan" target="_target"><i className="fa fa-google-plus-official" aria-hidden="true"></i> Google+</a></li>
	<li><a href="https://github.com/robwelan" target="_blank"><i className="fa fa-github" aria-hidden="true"></i> GitHub</a></li>
	<li><a href="https://gitlab.com/robwelan" target="_blank"><i className="fa fa-gitlab" aria-hidden="true"></i> GitLab</a></li>
	<li><a href="https://www.linkedin.com/in/robwelan" target="_blank"><i className="fa fa-linkedin" aria-hidden="true"></i> LinkedIn</a></li>
	<li><a href="https://www.freecodecamp.com/robwelan" target="_blank"><i className="fa fa-free-code-camp" aria-hidden="true"></i> freeCodeCamp</a></li>
</ul>
</div>
</div>
</div>
<div className="footer-copyright">
<div className="container">
            © 2017 Rob Welan | <a href="https://creatureoftech.com/" target="_blank">Creature of Tech</a></div>
</div>
</footer>

  )
}
const TopMenu = _ => {
  return (
<div className="nav-wrapper">
      <a href="#!" className="brand-logo">freeCodeCamp<i className="right fa fa-free-code-camp" aria-hidden="true"></i></a>
<ul className="right hide-on-med-and-down">
	<li><a href="sass.html"><i className="material-icons">search</i></a></li>
	<li><a href="badges.html"><i className="material-icons">view_module</i></a></li>
	<li><a href="collapsible.html"><i className="material-icons">refresh</i></a></li>
	<li><a href="mobile.html"><i className="material-icons">more_vert</i></a></li>
</ul>
</div>
)
}

class App extends React.Component {
  componentDidMount() {
    $(".button-collapse").sideNav();
  }
  render() {
    return (
<div>
<Nav><TopMenu /></Nav>

        <Container>
<h1>Hello World!</h1>
</Container>
<Footer /></div>
)
  }
}

ReactDOM.render(
  <App />,
  document.getElementById("app")
)

So, how does it work? I’m glad you asked.

The App class is creating our top level component. It is technically a stateful component because I’ve had to use “componentDidMount” in order to get some jQuery/Materialize.js to run. You can think of componentDidMount as roughly equivalent to $(document).ready() and as roughly equivalent to the onload event of an HTML body section.

Our App requires a DIV wrapper (because React). Within the DIV am including a functional (stateless) component, which is wrapping another functional (stateless) component.

Functional or Stateless components have no business but to present. They will react to changes in state (potentially), but they will not contain or manage state. Another way of thinking about functional / stateless components is that they include no application logic, but may react to changes in application logic.

A rare-ish code pattern:
You may have noticed some functions being written like this:

  const TopMenu = _ => {}

The “_” (underscore) in the code above is the equivalent of writing the following:

  const TopMenu = () => {}

That’s one less character to type! Giggity.

Our components that include child components include the {children} argument. This tells ReactJS to expect something to be passed into this type of component. This is how we can include Components inside of Components for example. Oh yeah!

You may have noticed that some returns() are returning something that kind of looks like HTML. It is JSX (which is ReactJS’s method of combining JavaScript, CSS and HTML, more-or-less). There are important things to be mindful of – since “class” is a reserved word in JavaScript, we have to modify the HTML reference of “class=” to “className=”. Otherwise, ReactJS will not be able to tell the difference between JavaScript and something that can be rendered as HTML. I forget this all the time and end up often wondering why my font-icons don’t render correctly. Don’t be like me. Sigh.

For Your Reference

Here’s the Pen.

Advertisements