Open tribou opened 6 years ago
This would let us move ALL the component handlers, lifecycle methods, and React state into the container. It might enable better sharing across RN/web with the exception of iOS/Android-specific modules that might need custom logic in the view still.
https://github.com/tysoncadenhead/coffee-ratios/blob/e27766e4f22fe16608ae93a89499edd22bbd701d/src/App.tsx#L12
class App extends React.Component <any, any> { constructor (props: any) { super(props); this.setSelectedCoffee = this.setSelectedCoffee.bind(this); this.toggleIsFavorite = this.toggleIsFavorite.bind(this); this.state = { selectedCoffee: null, favorites: {}, coffees: [] }; } setSelectedCoffee (selectedCoffee) { this.setState({ selectedCoffee }); } getFavorites () { fetchFavorites() .then(favorites => { this.setState({ favorites }); }); } getCoffees () { fetchCoffees() .then(coffees => { this.setState({ coffees }); }); } componentDidMount () { this.getCoffees(); this.getFavorites(); } toggleIsFavorite () { const id = this.state.selectedCoffee; const isFavorite = this.state.favorites[id]; if (isFavorite) { return removeFromFavorites(id) .then(favorites => { this.setState({ favorites }) }); } else { return addToFavorites(id) .then(favorites => { this.setState({ favorites }) }); } } render() { return ( <AppWrapper> <Thumbnails> {this.state.coffees.map(coffee => ( <Thumbnail id={coffee.id} key={coffee.id} isFavorite={this.state.favorites[ coffee.id ]} selectedCoffee={this.state.selectedCoffee} onClick={() => { this.setSelectedCoffee(coffee.id) }} /> ))} </Thumbnails> <Coffee id={this.state.selectedCoffee} key={this.state.selectedCoffee} isFavorite={this.state.favorites[ this.state.selectedCoffee ]} toggleIsFavorite={this.toggleIsFavorite} /> </AppWrapper> ); } }
https://github.com/tysoncadenhead/coffee-ratios/blob/4fcd6af14ee2b19a52b1bdcc831d1efe2bf4a3d4/src/App.tsx#L16
const App = props => ( <AppWrapper> <Thumbnails> {props.coffees.map(coffee => ( <Thumbnail id={coffee.id} key={coffee.id} isFavorite={props.favorites[ coffee.id ]} selectedCoffee={props.selectedCoffee} onClick={() => { props.setSelectedCoffee(coffee.id) }} /> ))} </Thumbnails> <Coffee id={props.selectedCoffee} key={props.selectedCoffee} isFavorite={props.favorites[ props.selectedCoffee ]} toggleIsFavorite={props.toggleIsFavorite} /> </AppWrapper> ); const getFavorites = props => fetchFavorites() .then(props.setFavorites); const getCoffees = props => fetchCoffees() .then(props.setCoffees); const toggleIsFavorite = R.curry((props, _e) => { const id = props.selectedCoffee; const isFavorite = props.favorites[id]; const request = R.ifElse( R.equals(true), R.always(removeFromFavorites), R.always(addToFavorites) )(isFavorite); return request(id).then(props.setFavorites); }); export default compose( withState('selectedCoffee', 'setSelectedCoffee', null), withState('favorites', 'setFavorites', {}), withState('coffees', 'setCoffees', []), componentDidMount( compose( R.tap(getCoffees), R.tap(getFavorites) ) ), withHandlers({ toggleIsFavorite }) )(App);
This would let us move ALL the component handlers, lifecycle methods, and React state into the container. It might enable better sharing across RN/web with the exception of iOS/Android-specific modules that might need custom logic in the view still.
Before
https://github.com/tysoncadenhead/coffee-ratios/blob/e27766e4f22fe16608ae93a89499edd22bbd701d/src/App.tsx#L12
After
https://github.com/tysoncadenhead/coffee-ratios/blob/4fcd6af14ee2b19a52b1bdcc831d1efe2bf4a3d4/src/App.tsx#L16