Reactium
Search
⌃K

Creating a Simple Single Page Web App (SPA)

The Reactium foundational framework can be used to build a stand-alone simple Web App. Need a quick React app with routed components, here's how you do it!

TL;DR - from the command line, run:

mkdir myapp
cd myapp
npx reactium init
[ARCLI] > Initialize what type of project?: (Use arrow keys)
❯ Reactium (Web Application)
Actinium (Web API)
# Delete the default component
rm -rf src/app/components/Welcome
# Create Your Home Page!
npx reactium component
[ARCLI] > Select directory: src/app/components
❯ src/app/components
src/app/components/common-ui
[ARCLI] > Component Name: Home
[ARCLI] > Route: /
[ARCLI] > Reactium Hooks?: Yes
[ARCLI] > Domain file?: Yes
[ARCLI] > Stylesheet?: Yes
[ARCLI] > Select stylesheet type:
base
atoms
molecules
❯ organisms
overrides
default
mixins
[ARCLI] > Preflight checklist:
{
"destination": "src/app/components/Home",
"name": "Home",
"route": "['/']",
"hooks": true,
"domain": true,
"style": true,
"styleType": "_reactium-style-organisms.scss",
"className": "home",
"index": true
}
[ARCLI] > Proceed?: (y/N) y
npm run local
That's it. You should be looking at a running simple app, with your Home component running on http://localhost:3000

Creating A Page

Let's break down what's happening with the previous reactium command. After proceeding, your scr/app directory should look something like this:
src/app
├── components
│ ├── Home
│ │ ├── Home.jsx
│ │ ├── reactium-domain-home.js <- defines the unique namespace of our component
│ │ ├── reactium-hooks-home.js <- Reactium plugin hooks go here
│ │ ├── reactium-route-home.js <- Defines the Route where this component renders in the front-end
│ │ └── _reactium-style-organisms-Home.scss <- Styles go here
└── main.js <- The main entry point of the app (usually no modifications needed)

Create a Second Page

npx reactium component
[ARCLI] > Select directory: src/app/components
❯ src/app/components
src/app/components/common-ui
[ARCLI] > Component Name: About
[ARCLI] > Route: /about
[ARCLI] > Reactium Hooks?: Yes
[ARCLI] > Domain file?: Yes
[ARCLI] > Stylesheet?: Yes
[ARCLI] > Select stylesheet type:
base
atoms
molecules
❯ organisms
overrides
default
mixins
[ARCLI] > Preflight checklist:
{
"destination": "src/app/components/About",
"name": "About",
"route": "['/about']",
"hooks": true,
"domain": true,
"style": true,
"styleType": "_reactium-style-organisms.scss",
"className": "about",
"index": true
}
[ARCLI] > Proceed?: (y/N) y

Single Page Application Navigation

You already have a React single-page application started.
Let's create a navigation component and render it on both pages!
npx reactium component
[ARCLI] > Select directory: common-ui
❯ src/app/components/common-ui
[ARCLI] > Component Name: Nav
[ARCLI] > Route:
[ARCLI] > Reactium Hooks?: (Y/n) Yes
[ARCLI] > Domain file?: (Y/n) Yes
[ARCLI] > Stylesheet?: (Y/n) Yes
variables
base
atoms
❯ molecules
organisms
overrides
default
(Move up and down to reveal more choices)
[ARCLI] > Preflight checklist:
{
"destination": "src/app/components/common-ui/Nav",
"name": "Nav",
"route": "[]",
"hooks": true,
"domain": true,
"style": true,
"styleType": "_reactium-style-molecules",
"className": "nav",
"index": true
}
[ARCLI] > Proceed?: (Y/n) Yes
Ok, let's modify our Nav component:
common-ui/Nav/Nav.jsx
import React from 'react';
import { NavLink } from 'react-router-dom';
/**
* -----------------------------------------------------------------------------
* Component: Nav
* -----------------------------------------------------------------------------
*/
export const Nav = ({ className }) => {
return (
<nav className={className}>
<NavLink to='/' exact={true} activeClassName='active'>
Home
</NavLink>
<NavLink to='/about' activeClassName='active'>
About
</NavLink>
</nav>
);
};
Nav.defaultProps = {
className: 'nav',
};
export default Nav;
Let's also add some sassy styles for Nav:
common-ui/Nav/_reactium-style-molecules-Nav.scss
.nav {
display: flex;
flex-direction: column;
padding: 20px;
a {
&, &:visited {
color: gray;
}
&:hover, &.active {
color: black;
}
}
}
Great, now let's include the Nav in both the Home page and the About page:
Home.jsx
About.jsx
import {
useSyncState,
useHookComponent,
} from '@atomic-reactor/reactium-core/sdk';
import React from 'react';
/**
* -----------------------------------------------------------------------------
* Component: Home
* -----------------------------------------------------------------------------
*/
export const Home = ({ className }) => {
const Nav = useHookComponent('Nav');
const state = useSyncState({ content: 'Home' });
return (
<div className={className}>
<Nav />
<h1>{state.get('content')}</h1>
<p>This is the Home page.</p>
</div>
);
};
Home.defaultProps = {
className: 'home',
};
export default Home;
/
import {
useSyncState,
useHookComponent,
} from '@atomic-reactor/reactium-core/sdk';
import React from 'react';
/**
* -----------------------------------------------------------------------------
* Component: About
* -----------------------------------------------------------------------------
*/
export const About = ({ className }) => {
const Nav = useHookComponent('Nav');
const state = useSyncState({ content: 'About' });
return (
<div className={className}>
<Nav />
<h1>{state.get('content')}</h1>
<p>This is the About page.</p>
</div>
);
};
About.defaultProps = {
className: 'about',
};
export default About;
/about

Great, Now we are SPA Routing!

But wait, does that mean I have to have common elements like the Nav on every routed page?
Let's create an AppParent component to be the "window dressing" for our app!
npx reactium component
[ARCLI] > Select directory: common-ui
❯ src/app/components/common-ui
[ARCLI] > Component Name: AppParent
[ARCLI] > Route:
[ARCLI] > Reactium Hooks?: (Y/n) Yes
[ARCLI] > Domain file?: (Y/n) Yes
[ARCLI] > Stylesheet?: (Y/n) Yes
variables
base
atoms
molecules
❯ organisms
overrides
default
(Move up and down to reveal more choices)
[ARCLI] > Preflight checklist:
{
"destination": "src/app/components/common-ui/AppParent",
"name": "AppParent",
"route": "[]",
"hooks": true,
"domain": true,
"style": true,
"styleType": "_reactium-style-organisms",
"className": "appparent",
"index": true
}
[ARCLI] > Proceed?: (Y/n) Yes
Let's move the Nav to the AppParent component, and add some common page structure to the app.
AppParent.jsx
_reactium-style-organisms-AppParent.scss
Home.jsx
About.jsx
_reactium-style-molecules-Nav.scss
import { useHookComponent } from '@atomic-reactor/reactium-core/sdk';
import React from 'react';
/**
* -----------------------------------------------------------------------------
* Component: AppParent
* -----------------------------------------------------------------------------
*/
export const AppParent = ({ className, children }) => {
const Nav = useHookComponent('Nav');
const Footer = useHookComponent('Footer');
return (
<main className={className}>
<aside className='main-nav'>
<Nav />
</aside>
<section className='main-content'>{children}</section>
<footer className='main-footer'>
<Footer />
</footer>
</main>
);
};
AppParent.defaultProps = {
className: 'appparent main',
};
export default AppParent;
Note that the Footer component need not actually already exist. If someone creates one with that name, it will just show up!
By creating an AppParent component that returns props.children, it will automatically take the place of the component in reactium-core. Registered components are overridden! A good thing!
.main {
padding: 50px;
&-nav, &-content {
border-bottom: 1px solid black;
}
&-content {
padding: 20px 0;
}
}
import { useSyncState } from '@atomic-reactor/reactium-core/sdk';
import React from 'react';
/**
* -----------------------------------------------------------------------------
* Component: Home
* -----------------------------------------------------------------------------
*/
export const Home = ({ className }) => {
const state = useSyncState({ content: 'Home' });
return (
<div className={className}>
<h1>{state.get('content')}</h1>
<p>This is the Home page.</p>
</div>
);
};
Home.defaultProps = {
className: 'home',
};
export default Home;
import { useSyncState } from '@atomic-reactor/reactium-core/sdk';
import React from 'react';
/**
* -----------------------------------------------------------------------------
* Component: About
* -----------------------------------------------------------------------------
*/
export const About = ({ className }) => {
const state = useSyncState({ content: 'About' });
return (
<div className={className}>
<h1>{state.get('content')}</h1>
<p>This is the About page.</p>
</div>
);
};
About.defaultProps = {
className: 'about',
};
export default About;
.nav {
display: flex;
a {
padding: 10px 20px;
&,
&:visited,
&:hover,
&:active {
text-decoration: none;
}
&,
&:visited {
color: gray;
}
&:hover,
&.active {
color: white;
background: gray;
}
}
}

Final Simple SPA

Front-end Routed Single Page Application