|
import createLogger from 'redux-logger'; |
|
import PureComponent from 'react-pure-render/component'; |
|
import React from 'react'; |
|
import ReactDOM from 'react-dom'; |
|
import { connect, Provider } from 'react-redux'; |
|
import { createStore, combineReducers, applyMiddleware, compose, bindActionCreators } from 'redux'; |
|
import { createModelReducer, createFormReducer, Field, actions } from 'react-redux-form'; |
|
import thunk from 'redux-thunk'; |
|
import './style.css'; |
|
|
|
/** |
|
* Reducers / Store |
|
*/ |
|
|
|
const reducers = combineReducers({ |
|
user: createModelReducer('user', { |
|
name: '', |
|
hobbies: { piano: false, surfing: false }, |
|
phones: [], |
|
}), |
|
userForm: createFormReducer('user') |
|
}); |
|
|
|
const finalCreateStore = compose( |
|
applyMiddleware(thunk, createLogger({ collapsed: true })) |
|
)(createStore); |
|
|
|
function configureStore(initialState) { |
|
const store = finalCreateStore(reducers, initialState); |
|
|
|
if (module.hot) { |
|
// Enable Webpack hot module replacement for reducers |
|
module.hot.accept('./index.js', () => { |
|
const nextRootReducer = reducers; |
|
store.replaceReducer(nextRootReducer); |
|
}); |
|
} |
|
|
|
return store; |
|
} |
|
|
|
/** |
|
* Components |
|
*/ |
|
|
|
class JSONDump extends PureComponent { |
|
constructor(props) { |
|
super(props); |
|
this._conuter = 1; |
|
} |
|
componentDidUpdate() { |
|
++this._conuter; |
|
} |
|
render() { |
|
const { value } = this.props; |
|
|
|
return ( |
|
<div className="code"> |
|
<span>({ this._conuter })</span> |
|
<pre>{ JSON.stringify(value, null, 2) }</pre> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
class Presentational extends PureComponent { |
|
render() { |
|
const { index, user, userForm, dispatch } = this.props; |
|
|
|
return ( |
|
<div> |
|
<h2>Demo</h2> |
|
|
|
<div> |
|
<Field model="user.name"> |
|
<label>name: </label> |
|
<input type="text" /> |
|
</Field> |
|
<JSONDump value={ user.name } /> |
|
</div> |
|
|
|
<div> |
|
<Field model="user.hobbies.piano"> |
|
<label>hobbies.piano</label> |
|
<input type="checkbox" /> |
|
</Field> |
|
<JSONDump value={ user.hobbies.piano } /> |
|
</div> |
|
|
|
<div> |
|
<Field model="user.hobbies.surfing"> |
|
<label>hobbies.surfing</label> |
|
<input type="checkbox" /> |
|
</Field> |
|
<JSONDump value={ user.hobbies.surfing } /> |
|
</div> |
|
|
|
<div> |
|
phones: <button onClick={ () => dispatch(actions.push('user.phones', Math.random()))}>+</button> |
|
<JSONDump value={ user.phones } /> |
|
</div> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
const Container = connect( |
|
state => ({ |
|
user: state.user, |
|
userForm: state.userForm, |
|
}) |
|
)(Presentational); |
|
|
|
/** |
|
* Entry Point |
|
*/ |
|
|
|
const store = configureStore(); |
|
|
|
ReactDOM.render( |
|
<Provider store={ store }> |
|
<Container /> |
|
</Provider>, |
|
document.querySelector('#app') |
|
); |