Created
April 30, 2018 09:04
-
-
Save jcuffe/a225d6bab88d1350633c4bb0f6372934 to your computer and use it in GitHub Desktop.
Load async data in React using functional components and observers, no state.
This file contains hidden or 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
import React from 'react' | |
import ReactDOM from 'react-dom' | |
import { Observable } from 'rxjs' | |
import 'rxjs/add/observable/combineLatest' | |
import firebase from 'firebase' | |
// Don't tell anyone my secrets | |
firebase.initializeApp({ | |
apiKey: "AIzaSyDMOIq693Xaj6Ieo10kJCo_uY30fY6lT-8", | |
authDomain: "lambda-front-end-f3a17.firebaseapp.com", | |
databaseURL: "https://lambda-front-end-f3a17.firebaseio.com", | |
projectId: "lambda-front-end-f3a17", | |
storageBucket: "lambda-front-end-f3a17.appspot.com", | |
messagingSenderId: "852639223993" | |
}) | |
// Grab a reference to the root of our data model | |
const notesRef = firebase.database().ref('notes') | |
const formatNote = snapShot => | |
Object.entries(snapShot.val()).map(([id, value]) => ({ id, value })) | |
// Whenever firebase's `listener` fires, emit a new value from our observable | |
const note$ = Observable.create((observer) => { | |
notesRef.on('value', (snapShot) => observer.next(formatNote(snapShot))) | |
}) | |
// Make a second Observable stream from some other database ref | |
const otherNote$ = Observable.create((observer) => { | |
notesRef.on('value', (ss) => observer.next(Object.values(ss.val()))) | |
}) | |
// Combine and namespace each of our streams to create our application state | |
const rootNote$ = Observable.combineLatest(note$, otherNote$, (notes, otherNotes) => ({ notes, otherNotes })) | |
// Some functional components | |
const App = ({ notes }) => ( | |
<div> | |
{notes.map((note, index) => ( | |
<Note {...note} key={index} /> | |
))} | |
</div> | |
) | |
const Note = ({ value: { title }, id }) => ( | |
<h1>{title} <em>{id}</em></h1> | |
) | |
// Put render inside a subscription to our root stream to enable access to the observable's values | |
rootNote$.subscribe(({ notes, otherNotes }) => { | |
ReactDOM.render(<App notes={notes} />, document.getElementById('root')); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment