generator-oh-react
v1.0.0-alpha3
Published
React Yeoman generator designed to speed up development.
Downloads
1
Readme
React App Generator
This is a generator based on my own experiences with React.
The application is structured as:
.eslintrc.json
.babelrc
LICENSE
gulpfile.js
package.json
webpack.config.js
src/
index.html
js/
index.jsx # Entry point
store.js # Redux store setup
defaultState.js # The default Redux state
actions/ # Actions for the application
ActionBase.js # Base action class
index.js # Bootstraps action classes for dispatch
manifest.json # Lists classes bootstrapped by index.js
components/ # React UI components
App.jsx # The root component of the application
spec/ # Unit tests
dist/ # Compilation (gulp/webpack) output
Action Architecture
Actions are created as subclasses of ActionBase
. All actions are listed in
the src/js/actions/manifest.json
file. This file is automatically updated
when you use the oh-react:action
generator. If you manually create action
classes you will need to list them in this file. During compilation this JSON
file is compiled to a Javascript file loaded by src/js/actions/index.js
.
The action index loads all action classes, creates an instance of each and
bootstraps actions
and actionHandlers
as exports. You should use actions
to dispatch actions against the store. actionHandlers
is bound to the Redux
store in src/js/store.js
.
Creating Actions
yo oh-react:action Foo.Bar.DoSomething
Afterwards your action class will be in
src/js/actions/Foo/Bar/DoSomethingAction.js
with a spec in
spec/actions/Foo/Bar/DoSomethingActionSpec.js
.
You should implement the DoSomethingAction#create
method to create a Redux
action object. You can then do the following to dispatch the action from
anywhere in your code:
import { actions } from "./actions"; // Relative path to actions/
// Invokes DoSomethingAction#create(<arguments>) and dispatches it on the
// bound Redux store.
actions.foo.bar.doSomething(<arguments>);
To handle the action, implement the DoSomethingAction#handle
method. This
will receive the state the action is bound to (which may be the full state or a
part of it) and the action object as arguments. You should return a new state
to replace the old.
Example:
import ActionBase from "./ActionBase";
export default class DoSomethingAction extends ActionBase {
constructor() {
super();
// This is the type of the action as defined by Redux. You should
// set `{ type: this.actionType }` in your #create()
// implementation.
this.actionType = "do-something";
// Used as the action function name
// (i.e., actions.foo.bar.doSomething()`).
this.actionKey = "foo.bar.doSomething";
// Specifies the path in the state object that this action changes.
// When DoSomethingAction#handle(state, action) is called this key
// is used to determine what state is passed as `state`.
this.stateKey = "foo.bar.doSomething";
}
/**
* This only gets called if action.type == this.actionType.
*/
handle(state, action) {
return { /* New State */ };
}
/**
* Create your action object that will be dispatched on the store.
*/
create(args) {
return { type: this.actionType, ...args };
}
}
Creating Components
A generator will be added to generate components. However you should simply
create a new React ES6-style class in js/components/
.
TODO
- Further documentation
- Component generator
- Support multiple action types per action
- Page (route) generation