Chapter 1 - Components

The purpose of this chapter is to create a few stateless views of our application using React.

Branch: To see the commits of this chapter checkout this branch.

Release: To skip this chapter just clone this release.


React

React is a library for building user interfaces. Why so much hype about this technology? Here are a few key points:

  • Component-based: simple components can be encapsulated and composed into more complex UIs.

  • Declarative: components can be just a functions that take properties and return JSX, making them predicatble and easy to debug, since data flows just in one way (in contrast to Angular's two-way bindings)

  • Virtual DOM: React holds a representation of the DOM and updates the actual DOM only when necessary by diff'ing the changes in the virtual DOM. This makes React very fast and also allows it to be rendered on the client, the server, or on mobile apps thru React Native

Now go ahead and install these deps:

npm install react react-dom --save
npm install react-loader --save-dev

Add react-hot to your webpack loaders:

{ 
  test: /\.js$/, 
  loaders: ['react-hot', 'babel'], 
  exclude: /node_modules/
},

So lets create a simple App component -> make a components folder inside src, and save the following file as src/components/App.js:

import React, { PropTypes } from 'react'
import styles from './App.css'

const App = (props) => ( 
  <div className={styles.header}> {props.text} </div>
)

App.propTypes = { 
  text: PropTypes.string.isRequired
}

export default App

And the following as src/components/App.css

.header { 
  font-size: 20px; 
  color: blue;
}

NOTE: there are different opinions about what folder structure to follow, some people separate components in individual folders, or by page in a nested fashion, or by feature, etc. I''ll let you figure out the folder structure that works best for you, I'll just drop all the js and css files in components by component name.

So we just created a component that receives a text property which is a string, and renders a <div> with that text in blue.

Now lets use this component and rendering using react-dom, save the following as src/index.js

import 'babel-polyfill'
import React from 'react'
import ReactDOM from 'react-dom'
import App from 'components/App'

const app = <App text='Hello Wolrd' />
const root = document.getElementById('root')

ReactDOM.render(app, root)

That will import our component, render it passing 'Hello Wolrd' as its text property, and mount it on the #root element of the document, using react-dom.

In order for this line to work:

import App from 'components/App'

We'll need to add an alias for components in our webpack config's resolve.alias:

resolve: { 
  alias: { 
    'components': 'src/components' 
  },
  ...
}

Test It Out:

Now just npm run dev-server and open up http://localhost:9999, you should see a blue Hello World in the screen.


Diff: to see the diff for this step click here.

Fast-forward: git clone --branch react https://github.com/cazala/universal-app.git --depth=1


React Toolbox

React Toolbox is a UI kit. We'll install it so we don't have to waste much time making the most basic components, but you don't actually need this to use React.

npm install --save react-toolbox react-addons-update react-addons-css-transition-group normalize.css
npm install --save-dev sass-loader node-sass

We'll need sass-loader in order to use React Toolbox from webpack.

So add it to the end of the loaders list for css files:

{ 
  test: /(\.scss|\.css)$/, 
  loaders: ['style', 'css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]', 'postcss', 'sass?sourceMap'] 
}

Also we can add a theme.css file at the root level of our app to set the colors of the variables:

@import "~react-toolbox/lib/colors";

$color-primary: #00A0DF !default;
$color-primary-dark: #00607C !default;
$color-accent: #77BC1F !default;
$color-accent-dark: #009444 !default;
$color-primary-contrast: #ffffff !default;
$color-accent-contrast: #646469 !default;

And just add this to webpack.config.js so the sass loader includes our theme.css variables:

sassLoader: { 
  data: '@import "' + path.resolve(__dirname, 'theme.css') + '";' 
},

You are all set.


Test It Out:

Add this line as your last import in src/components/App

import Button from 'react-toolbox/lib/button'

And change your App component to this:

const App = (props) => ( 
  <Button label={props.text} />
)

Now npm run dev-server and you should see this time a button that reads Hello Wolrd.


Diff: to see the diff for this step click here.

Fast-forward: git clone --branch react-toolbox https://github.com/cazala/universal-app.git --depth=1


results matching ""

    No results matching ""