Last active
February 28, 2018 16:04
-
-
Save fabriziomoscon/3e807fc0f78c408b55baf26b01543c6b to your computer and use it in GitHub Desktop.
Models allow code reuse between Components and reducers' action creators
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
// @flow | |
// model Collection | |
import Maybe from 'folktale/data/maybe' | |
import Result from 'folktale/data/result' | |
const MAX_VOLUME = 100 | |
type CollectionState = { | |
volume: number, | |
} | |
class Collection { | |
constructor(data: CollectionState) { | |
this._data = data | |
} | |
safeGetVolume(): Maybe<number> { | |
return Maybe.fromNullable(this._data) | |
.chain(d => Maybe.fromNullable(d.volume)) | |
} | |
// this is used by the Component and by the reducer's thunk | |
validateVolume(): Result<string, number> { | |
return this.safeGetVolume() | |
.map(volume => { | |
if (volume >= MAX_VOLUME) { | |
return Result.Error('Volume exceeding the maximum allowed') | |
} | |
return Result.Ok(volume) | |
}) | |
.getOrElse(Result.Error('Invalid volume')) | |
} | |
} | |
// Component Volume | |
import {Component}, React from 'react' | |
import {Text} from 'react-native' | |
type Props = { | |
data: CollectionState, | |
} | |
class Volume extends Component<Props>{ | |
constructor(props: Props) { | |
super(props) | |
this.collection = new Collection(props.data) | |
} | |
Collection: Collection | |
render() { | |
return this.collection.validateVolume() | |
.matchWith({ | |
Error: ({value}) => { | |
<Text style={styles.error}>{value}</Text> | |
}, | |
Ok: ({value}) => { | |
<Text>Volume: {value}yd</Text> | |
}, | |
}) | |
} | |
} | |
// collection reducer | |
function failedSetVolume(errMsg: string): Action { | |
return { | |
type: 'SET_VOLUME_FAILURE', | |
payload: { | |
errMsg, | |
}, | |
} | |
} | |
function successSetVolume(volume: number): Action { | |
return { | |
type: 'SET_VOLUME_SUCCESS', | |
payload: { | |
volume, | |
}, | |
} | |
} | |
// relevant reducer thunk | |
const setVolume = (collection: Collection) => (dispatch: Dispatch) => Action { | |
return collection.validateVolume() | |
.matchWith({ | |
Error: ({value}) => dispatch(failedSetVolume(value)), | |
Ok: ({value}) => dispatch(successSetVolume(value)), | |
}) | |
} | |
// reducer implementation omitted |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment