Skip to content

Instantly share code, notes, and snippets.

@jcuffe
Created April 30, 2018 09:04
Show Gist options
  • Save jcuffe/a225d6bab88d1350633c4bb0f6372934 to your computer and use it in GitHub Desktop.
Save jcuffe/a225d6bab88d1350633c4bb0f6372934 to your computer and use it in GitHub Desktop.
Load async data in React using functional components and observers, no state.
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