Skip to content

Commit

Permalink
Added a initial version of examples
Browse files Browse the repository at this point in the history
Closes #1
  • Loading branch information
dlmr committed May 12, 2016
1 parent 5889d47 commit 87509f5
Show file tree
Hide file tree
Showing 31 changed files with 736 additions and 0 deletions.
10 changes: 10 additions & 0 deletions examples/redux/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"presets": [
"es2015",
"stage-1",
"react"
],
"plugins": [
"transform-decorators-legacy"
]
}
6 changes: 6 additions & 0 deletions examples/redux/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import render from './render/client';
import routes from './routes';
import configureStore from './redux/configureStore';

const store = configureStore(__FLUX_STATE__);
render(document.getElementById('application'), routes, store);
27 changes: 27 additions & 0 deletions examples/redux/components/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { Component } from 'react';
import { Link, IndexLink } from 'react-router';

export default class App extends Component {
render() {
const { loading } = this.props
const style = {
opacity: loading ? 0.5 : 1,
transition: loading ? 'opacity 250ms ease 300ms' : 'false'
}

return (
<div style={style}>
<h1>React Router Redial Example</h1>
<ul>
<li>
<IndexLink to="/">Start</IndexLink>
</li>
<li>
<Link to ="/github">Github</Link>
</li>
</ul>
{this.props.children}
</div>
);
}
}
32 changes: 32 additions & 0 deletions examples/redux/components/Github.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { Component } from 'react';
import { Link } from 'react-router';

export default class Github extends Component {

constructor(props) {
super(props);
this.state = {value: ''};
}

onChange = (e) => {
this.setState({value: e.target.value});
}

render() {
const children = this.props.children ?
this.props.children :
(
<div>
<p>Please select a user by typing and clicking the link</p>
<input onChange={this.onChange} />&nbsp;
<Link to={{ pathname: `/github/user/${this.state.value}` }}>Open user!</Link>
</div>
);
return (
<div>
<h2>Github</h2>
{ children }
</div>
);
}
}
36 changes: 36 additions & 0 deletions examples/redux/components/Index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { Component } from 'react';
import { provideHooks } from 'redial';

@provideHooks({
fetch: ({ setProps, getProps, force }) => new Promise((resolve) => {
const { color } = getProps();
if(!color || force) {
setTimeout(() => {
const getValue = () => Math.round(Math.random() * 255);
setProps({color: `rgb(${getValue()}, ${getValue()}, ${getValue()})`});
resolve();
}, 1000);
} else {
resolve();
}
}),
defer: ({ setProps, getProps, force }) => {
const { data } = getProps();
if(!data || force) {
// Will be available as this.props.data on the component
setProps({ data: 'Client data' })
}
}
})
export default class Index extends Component {
render() {
return (
<div>
<h1 style={{ color: this.props.color }}>React Router Redial</h1>
<p>{ this.props.data }</p>
<button onClick={ () => this.props.reload() }>Reload color</button>
<pre>{ JSON.stringify(this.props, null, 2) }</pre>
</div>
);
}
}
28 changes: 28 additions & 0 deletions examples/redux/components/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { Component } from 'react';
import { provideHooks } from 'redial';
import { connect } from 'react-redux';

import fetchGithubUser from '../redux/actions/fetchGithubUser';

function mapStateToProps(state, ownProps) {
return { user: state.githubUsers[ownProps.params.id] }
}

@provideHooks({
fetch: ({ params: { id }, dispatch, getState }) => {
if(!getState().githubUsers[id]) {
return dispatch(fetchGithubUser(id));
}
}
})
@connect(mapStateToProps)
export default class Index extends Component {
render() {
return (
<div>
<h3>{ this.props.user.name } <pre>@{ this.props.user.login }</pre></h3>
<img src={ this.props.user.avatar_url } />
</div>
);
}
}
26 changes: 26 additions & 0 deletions examples/redux/devServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import koa from 'koa';
import webpack from 'webpack';
import koaWebpackDevMiddleware from 'koa-webpack-dev-middleware';

import webpackConfig from './webpack.config.js';

const devServer = koa();
const compiler = webpack(webpackConfig);

devServer.use(
koaWebpackDevMiddleware(compiler, {
publicPath: '/',
noInfo: false,
quiet: false
})
);

const hotMiddleware = require('webpack-hot-middleware')(compiler);
devServer.use(function* (next) {
yield hotMiddleware.bind(null, this.req, this.res);
yield next;
});

devServer.listen(3001);

console.log('Dev server started on http://localhost:3001');
36 changes: 36 additions & 0 deletions examples/redux/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "react-router-redial-redux-example",
"version": "0.0.0",
"description": "React Router Redial Redux example",
"scripts": {
"start": "babel-node server.js"
},
"license": "MIT",
"dependencies": {
"isomorphic-fetch": "2.2.1",
"koa": "1.2.0",
"nunjucks": "2.4.2",
"react": "15.0.2",
"react-dom": "15.0.2",
"redux-devtools": "3.2.0",
"redux-devtools-dock-monitor": "1.1.1",
"redux-devtools-log-monitor": "1.0.11",
"redux-logger": "2.6.1",
"redux-thunk": "2.1.0"
},
"devDependencies": {
"babel-cli": "6.8.0",
"babel-core": "6.8.0",
"babel-loader": "6.2.4",
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-preset-es2015": "6.6.0",
"babel-preset-react": "6.5.0",
"babel-preset-stage-1": "6.5.0",
"koa-webpack-dev-middleware": "1.2.0",
"react-router": "2.4.0",
"react-router-redial": "0.1.3",
"redial": "0.4.1",
"webpack": "1.13.0",
"webpack-hot-middleware": "2.10.0"
}
}
12 changes: 12 additions & 0 deletions examples/redux/redux/actions/fetchGithubUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import fetch from 'isomorphic-fetch';

export default function fetchGithubUser(userId) {
return (dispatch) => {
return fetch(`https://api.github.com/users/${userId}`)
.then((response) => response.json())
.then((user) => dispatch({
type: 'USER_LOADED',
payload: user
}))
}
}
21 changes: 21 additions & 0 deletions examples/redux/redux/configureStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'

export default function configureStore(initialState) {
const store = createStore(
combineReducers(require('./reducers')),
initialState,
applyMiddleware(thunk, createLogger()),
)

if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('./reducers', () => {
const nextRootReducer = combineReducers(require('./reducers'))
store.replaceReducer(nextRootReducer)
})
}

return store
}
11 changes: 11 additions & 0 deletions examples/redux/redux/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function githubUsers(state = {}, action) {
switch (action.type) {
case 'USER_LOADED':
return {
...state,
[action.payload.login]: action.payload
};
default:
return state;
}
}
43 changes: 43 additions & 0 deletions examples/redux/render/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { RedialContext } from 'react-router-redial';

import React from 'react';
import { render } from 'react-dom';
import { Router, browserHistory } from 'react-router';
import { Provider } from 'react-redux';

// Render the app client-side to a given container element:
export default (container, routes, store) => {
// Define extra locals to be provided to all lifecycle hooks:
const locals = store ? {
dispatch: store.dispatch,
getState: store.getState,
} : {};

let component = (
<Router
history={browserHistory}
routes={routes}
render={(props) => (
<RedialContext
{ ...props }
locals={locals}
blocking={['fetch']}
defer={['defer', 'done']}
parallel={false}
initialLoading={() => <div>Loading…</div>}
/>
)}
/>
);

if (store) {
component = (
<Provider store={store}>
{component}
</Provider>
);
}

// Render app to container element:
render(component, container);
};
42 changes: 42 additions & 0 deletions examples/redux/render/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { triggerHooks, RedialContext } from '../../../lib/index';

import React from 'react';
import { renderToString } from 'react-dom/server';
import { createMemoryHistory, match } from 'react-router';
import { Provider } from 'react-redux';

// Render the app server-side for a given path:
export default (path, routes, store) => new Promise((resolve, reject) => {
// Set up history for router:
const history = createMemoryHistory(path);

// Match routes based on history object:
match({ routes, history }, (error, redirectLocation, renderProps) => {

// Define extra locals to be provided to all lifecycle hooks:
const locals = store ? {
dispatch: store.dispatch,
getState: store.getState
} : {};

// Wait for async data fetching to complete, then render:
triggerHooks({
renderProps,
locals,
hooks: [ 'fetch', 'done' ]
}).then(({ redialMap, redialProps }) => {
const state = store ? store.getState() : null;
const component = <RedialContext {...renderProps} redialMap={ redialMap } />;
const html = store ? renderToString(
<Provider store={store}>
{ component }
</Provider>
) : renderToString(component);

// Important that the redialProps are sent to the client
// by serializing it and setting it on window.__REDIAL_PROPS__
resolve({ html, state, redialProps });
})
.catch(reject);
});
});
16 changes: 16 additions & 0 deletions examples/redux/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { Router, Route, IndexRoute } from 'react-router'

import App from './components/App';
import Index from './components/Index';
import Github from './components/Github';
import User from './components/User';

export default (
<Route path="/" component={App}>
<IndexRoute component={Index}/>
<Route path="github" component={Github}>
<Route path="user/:id" component={User} />
</Route>
</Route>
)
24 changes: 24 additions & 0 deletions examples/redux/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import koa from 'koa';
import nunjucks from 'nunjucks';

import render from './render/server';
import routes from './routes';
import configureStore from './redux/configureStore';

require('./devServer');

nunjucks.configure(__dirname);

const server = koa();
server.use(function *() {
const store = configureStore();
const result = yield render(this.url, routes, store);
this.body = nunjucks.render('template.html', {
...result,
state: JSON.stringify(result.state),
redialProps: JSON.stringify(result.redialProps)
});
});

server.listen(3000);
console.log('Server started on http://localhost:3000');
14 changes: 14 additions & 0 deletions examples/redux/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="application">{{ html | safe }}</div>

<script>window.__FLUX_STATE__ = {{ state | safe }}</script>
<script>window.__REDIAL_PROPS__ = {{ redialProps | safe }}</script>

<script src="http://localhost:3001/bundle.js"></script>
</body>
</html>
Loading

0 comments on commit 87509f5

Please sign in to comment.