Last active
October 22, 2017 08:34
-
-
Save reneviering/4e98674df45843e85540b646b80b8501 to your computer and use it in GitHub Desktop.
Simple Domain Object to hold simple application state in react.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Higher order component to connect the Domain to the component | |
const connectDomainToComponent = (WrappedComponent, Domain) => { | |
return class extends React.Component { | |
constructor() { | |
super(); | |
this.domain = new Domain(); | |
if (typeof(this.domain.getState) !== 'function') throw new Error('There is no function getState(…)') | |
const initialState = this.domain.getState(); | |
if (typeof(initialState) !== 'object') throw new Error('The domain state has to be an object'); | |
this.state = initialState; | |
} | |
update = (newDomainObject) => { | |
if (typeof(newDomainObject.then) === 'function') { | |
newDomainObject.then(newDomainObjectResult => { | |
this.domain = newDomainObjectResult; | |
if(typeof(newDomainObjectResult.getState) !== 'function') { | |
throw new Error('Looks like your domain type is not immutable. Make it immutable or ¯\_(ツ)_/¯') | |
} | |
this.setState(newDomainObjectResult.getState()); | |
}) | |
} else { | |
this.domain = newDomainObject; | |
if(typeof(newDomainObject.getState) !== 'function') { | |
throw new Error('Looks like your domain type is not immutable. Make it immutable or ¯\_(ツ)_/¯') | |
} | |
this.setState(newDomainObject.getState()); | |
} | |
} | |
render() { | |
return <WrappedComponent domain={this.domain} update={this.update} {...this.state} /> | |
} | |
}; | |
}; | |
// Counter-Domain | |
class Counter { | |
constructor(count = 0) { | |
this.state = { count }; | |
} | |
getState() { | |
return this.state; | |
} | |
increment() { | |
return new Counter(this.state.count + 1); | |
} | |
decrement() { | |
return new Counter(this.state.count - 1); | |
} | |
} | |
class App extends React.Component { | |
constructor() { | |
super(); | |
} | |
componentDidMount() { | |
} | |
handleIncrement = () => { | |
this.props.update(this.props.domain.increment()); | |
} | |
handleDecrement = () => { | |
this.props.update(this.props.domain.decrement()); | |
} | |
render() { | |
return ( | |
<div> | |
<p>{this.props.count}</p> | |
<button onClick={this.handleIncrement}>Increment</button> | |
<button onClick={this.handleDecrement}>Decrement</button> | |
</div> | |
); | |
} | |
} | |
const AppWithDomain = connectDomainToComponent(App, Counter); | |
ReactDOM.render( | |
<AppWithDomain/>, | |
document.getElementById('app') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment