Skip to content

Opinionated wrapper for quick prototyping with React, Redux and Firebase

Notifications You must be signed in to change notification settings

hoppula/refire-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

refire-app

Opinionated wrapper for quick prototyping with React, Redux and Firebase

Quick start

  1. Install create-react-app with npm install -g create-react-app
  2. Generate your React app, e.g. create-react-app my-app and cd my-app
  3. Install refire-app with npm install -S refire-app
  4. Paste following code over previous content in src/index.js and run the app with npm start
import React from 'react'
import refireApp, { IndexRoute, Route, Link, bindings, styles } from 'refire-app'

const nameStyles = { textTransform: "capitalize" }

const App = (props) => (<div>{props.children}</div>)

const Dinosaurs = styles(
  { name: nameStyles, container: { listStyle: "none" } },
  bindings([ "dinosaurs" ])(({ dinosaurs: dinos, styles }) => {
    if (!dinos) return (<div>Loading...</div>)
    const { value: dinosaurs = [] } = dinos || {}
    return (
      <div>
        <h1>Dinosaurs</h1>
        <ul className={styles.container}>
        {
          dinosaurs.map(({key}) => (
            <li key={key} className={styles.name}>
              <Link to={`/${key}`}>{key}</Link>
            </li>
          ))
        }
        </ul>
      </div>
    )
  })
)

const Dinosaur = styles(
  { name: nameStyles },
  bindings([ "dinosaur", "score" ])(({ dinosaur: dino, score: dinoScore, styles }) => {
    if (!dino || !dinoScore) return (<div>Loading...</div>)
    const { value: dinosaur = {}, key: name } = dino || {}
    const { value: score = {} } = dinoScore || {}
    return (
      <div>
        <h1 className={styles.name}>{name}</h1>
        <h2>{score} points</h2>
        <ul>
          <li>Order: {dinosaur.order}</li>
          <li>Appeared: {dinosaur.appeared} years ago</li>
          <li>Vanished: {dinosaur.vanished} years ago</li>
          <li>Height: {dinosaur.height} m</li>
          <li>Length: {dinosaur.length} m</li>
          <li>Weight: {dinosaur.weight} kg</li>
        </ul>
        <Link to="/">Back to dinosaurs list</Link>
      </div>
    )
  })
)

const apiKey = 'your-api-key-from-firebase-console-not-needed-in-this-example'
const projectId = 'dinosaur-facts'

const firebaseBindings = {
  "dinosaurs": { type: "Array", path: "dinosaurs" },
  "dinosaur": {
    type: "Object",
    path: (state) => {
      const { dinosaurId } = state.routing.params
      return dinosaurId ? `dinosaurs/${dinosaurId}` : null
    }
  },
  "score": {
    type: "Object",
    path: (state) => {
      const { dinosaurId } = state.routing.params
      return dinosaurId ? `scores/${dinosaurId}` : null
    }
  }
}

const routes = (
  <Route path="/" component={App}>
    <IndexRoute component={Dinosaurs} />
    <Route path=":dinosaurId" component={Dinosaur} />
  </Route>
)

refireApp({
  apiKey,
  projectId,
  bindings: firebaseBindings,
  routes,
  elementId: "root"
})

refireApp(options={})

Initializes redux, react-router, react-router-redux-params and refire.

options

apiKey Firebase api key

projectId Firebase project id

bindings Refire bindings

routes React Router routes

reducers = {} Additional redux reducers

middleware = [] Additional redux middleware

history = browserHistory Which type of history react-router should use

elementId = 'app' DOM element id for your app

Component wrappers

bindings([])

import React, { Component } from 'react'
import { bindings } from 'refire-app'
class YourComponent extends Component {
  render() {
    // board & boardThreads data available as props, re-rendered automatically as data changes
  }
}
export default bindings(["board", "boardThreads"])(YourComponent)

styles({})

Wrapper for react-free-style, your styles will be automatically inserted to a style tag at app's root level with unique classnames.

Styles can be defined as plain JS objects, this means you can use libraries like color or prefix-lite to enhance your styles.

import React, { Component } from 'react'
import { styles } from 'refire-app'
class YourComponent extends Component {
  render() {
    const { styles } = this.props
    return (
      <div className={styles.container}>
        ...
      </div>
    )
  }
}
export default styles({
  container: {
    padding: "30px 0",
    background: "#000",
    color: "#fff"
  }
}, YourComponent)

You can also allow your components to be easily extended by users, any component wrapped with styles will accept styles prop to be passed in and those styles will be merged with existing styles.

import React, { Component } from 'react'

class UserComponent extends Component {
  render() {
    // we want more top & bottom padding, other container styles will stay as they were defined in YourComponent
    return (
      <div>
        <YourComponent styles={{container: {padding: "50px 0"} }} />
      </div>
    )
  }
}

export default UserComponent

Exports

  • firebaseToProps
  • FirebaseLogin
  • FirebaseLogout
  • FirebaseOAuth
  • FirebaseRegistration
  • FirebaseResetPassword
  • FirebaseWrite
  • firebase
  • USER_AUTHENTICATED
  • USER_UNAUTHENTICATED
  • connect
  • bindActionCreators
  • Link
  • IndexLink
  • IndexRedirect
  • IndexRoute
  • Redirect
  • Route
  • browserHistory
  • hashHistory
  • routeActions
  • create (as createStyles)

Real world example

refire-forum is built with refire-app.

Live demo

License

MIT

About

Opinionated wrapper for quick prototyping with React, Redux and Firebase

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published