Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the plan for moving to ES6? #38

Closed
zoomclub opened this issue Mar 28, 2015 · 59 comments
Closed

What is the plan for moving to ES6? #38

zoomclub opened this issue Mar 28, 2015 · 59 comments

Comments

@zoomclub
Copy link

React is phasing out mixins with the change to ES6 classes. What is the plan for the reactfire mixin with this coming change? Could reactfire also tie in with react contexts? Below is a link to the context approach:

https://blog.jscrambler.com/react-js-communication-between-components-with-contexts

React relay with graphql is another approach coming to react. It would seem like reactfire updated to work with ES6 classes and the context approach might be a powerful alternative to relay with added collaboration! It might also work to incorporate some of the graphql as well?

@jwngr
Copy link

jwngr commented Apr 9, 2015

No plans at the moment, although I'd gladly comment on any PRs you send my way. We've been discussing how to get Firebase working with React Native and I think this also ties into that a little bit. Do you have any concrete ideas here?

@jwngr jwngr added the question label Apr 9, 2015
@zoomclub
Copy link
Author

zoomclub commented Apr 9, 2015

Great to learn about the discussion on Firebase and RN integration! In terms of component development I'm just looking for the optimal way for Firebase to provide the data and then for editing that data on a component, in light of the rapid progress being made with ES6 and React.

There are a number of proposals out there (the ones I mentioned) and I'm considering them in the context of the app I'm engineering. I have an app with more than just a couple gears to it so it provides the dynamic to work with, I'll be in touch with what I resolve.

@andyfen
Copy link

andyfen commented Jul 5, 2015

Hi, any development on how to use
mixins: [ReactFireMixin],

in ES6?
for a react project not react native.
thanks.

@jwngr
Copy link

jwngr commented Jul 5, 2015

There are still no active plans to update ReactFire for ES6 / React Native. You may want to check out re-base (https://github.com/tylermcginnis/re-base) which may fulfill your needs.

@pandaiolo
Copy link

+1

3 similar comments
@rstormsf
Copy link

rstormsf commented Aug 2, 2015

+1

@juancarlosfarah
Copy link

+1

@dlrice
Copy link

dlrice commented Aug 29, 2015

+1

@ghost
Copy link

ghost commented Aug 29, 2015

React is phasing out mix-ins with the change to ES6 classes.

The React team chose not to allow the existing mix-in pattern when creating a React component the ES6 way because JS doesn't currently have a standard method for doing mix-ins. So React.createClass and existing mix-in usage for components probably won't go anywhere until JS has an approved spec for mix-ins. Why not take the wait and see approach rather than trying to blaze that trail?

The nice thing is you can mix both ES6 class and createClass approaches for creating React components in your apps, and simply prefer one over the other until the path forward becomes evident.

@HighOnDrive
Copy link

There are new frameworks like Cycle.js than need a Firebase driver too. The driver is their specific way of adding a service to Cycle.js.

IDEA! Instead of Firebase always making a specific package per given framework why not create a core dropin service and then a set of plugins for specific things like Relay, Falcor, etc. Actually, Relay and Falcor are less robust copycats of Firebase any ways and the core aspects of Firebase should remain the main focus.

Surely, it is not the best to always have to completely customize per framework. Would it not be better for Firebase to instead provide a ES6 module with the essential core features available as higher order functions and then provide plugins for the rest?

This could always be done using the existing Firebase API but there is still a lot of re-inventing the wheel per project that way. To me Firebase stands on its own as a global service to XYZ framework components and the bridge into the specific component architecture of a given framework should be as thin as possible.

It is to be expected that any savvy framework can work with ES6 modules and a library of higher order functions. While a framework may come and go Firebase does not!

@jwngr
Copy link

jwngr commented Sep 10, 2015

Not a bad idea @HighOnDrive. I know you'd really like to see a Cycle.js driver, but we just don't have the resources right now to investigate and develop one. We'd love to see something come out of the community though!

As for your idea about creating an ES6 module with core features, I think that is compelling. For example, it certainly would be nice to not have to recreate the realtime array logic for every new binding. However, with our core product, we need to be more cautious for many reasons: a lot more people use it, a lot more people abuse it, and we support a lot of legacy browsers. With things like ReactFire, we can be more aggressive, dropping support for old browsers and providing APIs which people may (unintentionally) abuse. It's a tough line to tread and in order for us to move it into the core SDK, we need to be very sure of it.

I appreciate the discussion here and I hope it continues. I'd love to hear more about your ideas here!

@rstormsf
Copy link

resources can be solved by hiring :-)

@ghost
Copy link

ghost commented Oct 25, 2015

Parse maintains a similar mixin for connecting to React, but also provides a method for using ES6 classes for use with observables a la RxJS and the related React proposal. Is that something which seems worthwhile? Regardless users can still leverage REST and Flux, and leverage the new Firebase CLI tools for Node while building.

@nelix
Copy link

nelix commented Nov 7, 2015

I had a little go at designing a fresh firebase API as a higher order component. This is what I came up with.

const ref = new FirebaseEndpoint('https://myapp.firebaseio.com');

@connectFirebase((props) => {
  return { // this allows us to reconfigure when out targets props change
          // if needed this could also prolly return a promise
    endpoint: ref, // should allow passing this via this.context too
    keys: {
      user: '/users/$userid',
      messages: `/rooms/${props.roomId}/messages`,
    },
    paths: {
      '/users/$userid': null,
      `/rooms/${props.roomId}/messages`: {
        isArray: true,
        query: {
          limitToLast: 10,
        },
      },
    },
  };
}, (keys, states, actions) => {
  return { // this object becomes assigned to the wrapped components props
   // we can also require more complicated actions and state reducers here and mix them in in more complex apps
    user: states[keys.user],
    messages: states[keys.messages],
    updateUser: ({name}) => actions[keys.user].set({name}), // firebase will automatically trigger a change even right away and keep the props update
  };
})
class App extends Component {
  render() {
    const {updateUser, user} = this.props;

    return (
      <div>
        Hi <input value={user.firstname} onChange={(evt) => updateUser(evt.target.value)} type="text"/>
      </div>
    );
  }
}

@HighOnDrive
Copy link

We need a RxJS module for Firebase that is not tied into any specific framework. The same module could then work with all the frameworks that have already moved to RxJS. When is Firebase going to quit sitting on their asses about this and get with the program!?

I mean it's a new day now with FRP in the picture, just check out what happened at the Reactive 2015 conference or the RxJS videos being presented from Angular2 events, etc, etc. etc, etc.

Cycle.js also made a real dent in the universe at Reactive 2015, here is an article in case anyone wants a jump start on the future: https://medium.com/@fkrautwald/plug-and-play-all-your-observable-streams-with-cycle-js-e543fc287872

@remojansen
Copy link

👍 GraphQL & RxJS would be awesome!

@kulakowka
Copy link

It can help to mixin into react es6 component https://github.com/brigand/react-mixin

import React, { Component } from 'react'
import Firebase from 'firebase'
import ReactFireMixin from 'reactfire'
import reactMixin from 'react-mixin'

const ref = new Firebase('https://<APPNAME>.firebaseio.com/users')

class UsersList extends Component {
  constructor (props, context) {
    super(props, context)
    this.state = {
      users: []
    }
  }

  componentDidMount () {
    this.bindAsArray(ref, 'users')
  }

  renderUser (user) {
    return <p>{user.name}</p>
  }

  render () {    
    return (
      <div>
        {this.state.languages.map(this.renderLanguage)}    
      </div>
    )
  }
}

reactMixin(UsersList.prototype, ReactFireMixin)

export default UsersList

I created gist. You can fork it here: https://gist.github.com/kulakowka/24bb83775358ad4c3bc7

@rbarman
Copy link

rbarman commented Mar 13, 2016

  • 1

@ghost
Copy link

ghost commented Mar 13, 2016

ES6 is dead. Long live COBOL!

@katowulf
Copy link

image

@katowulf
Copy link

Jacob's answer continues to be the latest and greatest. Posts adding value on how devs can get up to speed on ES 6 or working toward a PR are welcome. Posts asking for release dates or discussing other features will be pruned. Please keep discussion on topic and productive.

@fdidron
Copy link

fdidron commented Jun 3, 2016

Hello

Here is a proposal for a PR.
Provide a single method à la redux "connect" that provides the current mixin methods to the component class.
EDIT: The terminology seems to be a High Order Component
Usage would look like:

import { Component } from 'react';
import reactFire from 'reactfire';

class MyComponent extends Component {

}

export default reactFire(MyComponent);

//OR ES7 decorator style

@reactFire()
export default class MyComponent extends Component {

}

@fdidron
Copy link

fdidron commented Jun 4, 2016

So here is a first shot at it
https://gist.github.com/fdidron/bde084f08ce64025ffba4f57c4eb441a

There is an API breaking change, since it's using a high order component, everything happens in your component's props.
So you access ReactFire methods via props : this.props.bindAsArray , ...
And the binded data can be found in the props of your component instead of the state.

@davideast
Copy link
Collaborator

@fdidron I love the decorator idea. With many devs using Babel this could be a nice syntactic gain that still achieves the same idea as the mixin.

@1j01
Copy link

1j01 commented Jul 17, 2016

I think A component is way overcomplicating the API. It should just be a single call to attach methods to the class or instance, or just static methods on the ReactFire object that take a this property:

class User extends React.Component {
  constructor (props) {
    fPosition = props.fPlayer.child("position")
    fContacts = props.fPlayer.child("contacts")
    ReactFire.bindAsObject(this, "position", fPosition)
    ReactFire.bindAsArray(this, "contacts", fContacts)
  }
  render () {
    {contacts, position} = state
    {x, y} = position
    <div class="user" style={left: x, top: y}>
      <Contacts contacts={contacts}/>
    </div>
  }
}

(Those methods could do some initialization the first time something is binded, and overload the componentWillUnmount, removing listeners and calling the original. Perhaps not the cleanest solution internally, but it would make for a nice succinct API.)

@frederikcreemers
Copy link

@1j01 That requires any object that wants to use Firebase to be a class, so you can't use it with function components. I still think a container is the most flexible option. Anything where you still need to manage binding/unbinding requires keeping state, which I think you should avoid as much as possible.

@1j01
Copy link

1j01 commented Jul 17, 2016

@bigblind Okay, well I didn't consider function components (I've never used them)
Has ReactFire previously worked with function components? (And does it really need to?)

@frederikcreemers
Copy link

frederikcreemers commented Jul 18, 2016

I just spent 3 hours writing an elaborate answer to this question only then to accidentally open another page in that tab... 😭

Here's the gist of it:

  • It's a good idea to divide your app into presentational/container components. There's a great article on this by Dan Abramov.
  • Most of your app can be presentational components, which can be pure functions that take props and render html.
  • Container components are responsible for fetching data.
  • If you write container components for every binding to Firebase you'd like to make, they'll all look very similar, not DRY.
  • We can create a factory for these container components. Component factories are Higher Order Components (HOCs). So we can just declaratively specify how we want our component to be bound, and our factory function will create such a component.
  • Look at my pull request to see an example implementation of what such a function might look like.

I might update this post with more useful links when I'm less depressed about browsers not saving draft form responses... 3 hours... wasted.

@1j01
Copy link

1j01 commented Jul 18, 2016

@bigblind What browser are you using? Chrome seems pretty good about saving things, navigating forwards, backwards, closing and reopening tabs. Not that I haven't lost plenty of stuff to Chrome.

Anyways, seems like a reasonable approach.

@birdwell
Copy link

Hey, what's the current status of this conversation?

@jwngr
Copy link

jwngr commented Aug 10, 2016

I actually finally found some time this past weekend to test out a new HOC API myself. I am hoping to have a proposal in PR form soon. I'm leaning towards going with an API similar to what @bigblind suggested, but there are still a few performance concerns that need to be figured out (mainly around re-binding Firebase listeners upon changes to props).

@prescottprue
Copy link
Contributor

@jwngr That is awesome to hear! Excited to check it out.

@birdwell
Copy link

@jwngr Sweet, I will be eagerly waiting! @prescottprue love your v3 lib on firebase redux! That's what's keeping me a float currently.

@prescottprue
Copy link
Contributor

Thanks @birdwell, that is exactly what it is for!

For those who haven't seen it: redux-firebasev3 was made as a way to get v3 implemented in React/Redux. I figure that ReactFire will take its place eventually, but I needed a solution before then.

@oscar-b
Copy link

oscar-b commented Aug 11, 2016

Same with re-base, there's a PR awaiting merge which adds v3 support: tylermcginnis/re-base#104

@mkozhukharenko
Copy link

mkozhukharenko commented Aug 19, 2016

@oscar-b re-base is already updated to v3

@marcello3d
Copy link

marcello3d commented Sep 12, 2016

Here's a completely different approach I've been experimenting with:
https://gist.github.com/marcello3d/0e9a1e532954f67c1fbb67c7d18319a6

I'm bypassing ReactFire altogether, and instead made two APIs:

  1. A higher-order component inspired by react-resolver but uses Observables instead of Promises
  2. A collection of functions that create Observables from Firebase database.References.

Example usage:

import React from 'react'

import { observeValue, observeCurrentUser } from './firebase-observable'
import connectObserver from './connect-observer'

export default connectObserver({
  // function takes props and returns an Observable or Promise
  post: ({ postId }) => observeValue(firebase.database().ref('/posts').child(postId)),
  user: () => observeCurrentUser(firebase.auth())
})(class Post extends React.Component
  static propTypes = {
    postId: React.PropTypes.string.isRequired,
    post: React.PropTypes.shape({}),
    user: React.PropTypes.object
  };
  render () {
    const { post, user } = this.props
    return 
  }
}))

@ghost
Copy link

ghost commented Sep 19, 2016

Do the owners of the reactfire repo have a recommended approach, or stated plans for using reactfire w/out mixins?

@jwngr
Copy link

jwngr commented Sep 19, 2016

@hyperbrave - #38 (comment) is still the latest. I really want to get this out but I haven't found the time to finish my proposal yet.

@vimtaai
Copy link

vimtaai commented Sep 29, 2016

Hi!
I've been working on a library of my own for a while, and finally I managed to get it to a stage that it's ready for sharing. (altough there still may be bugs) I'm starting to use it for a project of my own.
The main idea is to implement the Flux architecture with Google Firebase as the store and using Rx for the unidirectional flow. Although it is completely independent of React it works quite well with it. It also features a local in-memory storage with similar one-way data binding to variables or callbacks.
Check out the library at https://kozta.github.io/fluxbase
Any ideas, comments, questions are welcome.

@zoomclub
Copy link
Author

Wow, time marches on and life improves! Just saw this issue popup again and wanted to say that I did find a awesome solution that is built on RxJS. You may of heard of it by now, it’s called RethinkDB Horizon, see link below for more:

https://horizon.io

On Nov 7, 2015, at 12:54 PM, Stardrive Engineering notifications@github.com wrote:

We need a RxJS module for Firebase that is built for RxJS and not tied into any specific framework. The same module could then work with all the frameworks that have already moved to RxJS. When is Firebase going to quit sitting on their asses about this and get with the program!?

I mean it's a new day now with FRP in the picture, just check out what happened at the Reactive 2015 conference or the RxJS videos being presented from Angular2 events, etc, etc. etc, etc.

Cycle.js also made a real dent in the universe at Reactive 2015, here is an article in case anyone wants a jump start on the future: https://medium.com/@fkrautwald/plug-and-play-all-your-observable-streams-with-cycle-js-e543fc287872 https://medium.com/@fkrautwald/plug-and-play-all-your-observable-streams-with-cycle-js-e543fc287872

Reply to this email directly or view it on GitHub #38 (comment).

@daslicht
Copy link

How about TypeScript ?

@apieum
Copy link

apieum commented Dec 2, 2016

In case it helps, this simple HOC works, even if there is better solution.

import ReactFireMixin from 'reactfire';

const ReactFire = ParentComponent => class extends ParentComponent {
  static displayName = 'ReactFire' + (ParentComponent.displayName || 'ExtendedComponent');
  constructor(props) {
    super(props);
    // properties should be:
    // componentWillMount, componentWillUnmount, bindAsArray, bindAsObject, unbind
    for (var property in ReactFireMixin) {
      if (ReactFireMixin.hasOwnProperty(property)) {
        let value = ReactFireMixin[property];
        if (property in this) {
          let method = this[property].bind(this);
          let rfMethod = ReactFireMixin[property].bind(this);
          value = (function(...args) {
            method(...args);
            rfMethod(...args);
          });
        }
        Object.defineProperty(this, property, {value: value.bind(this)});
      }
    }
  }
};
export default ReactFire;

@theobouwman
Copy link

I dont understand why there is no good solution for this?

@fongandrew
Copy link

With respect to the pending HOC API and performance issues when props change, I suspect the concern is that (a) refs are equivalent even though there's been a props change, and (b) we don't want to incur the overhead of unbinding and rebinding to an equivalent ref.

Basically, we just need some way to check Firebase refs for "equality", right? That is, is there some way to do the following?

let x = firebase.database().ref('/items').orderByValue();
let y = firebase.database().ref('/items').orderByValue();
x.equiv(y) // => true

If there was, it'd make it trivial to handle the binding/rebinding performance concerns. We'd check if two refs are equivalent, and if they are, don't rebind.

Alternatively, the HOC API could require that users provide some sort of key string for each ref to help with comparison (this would be distinct from the state key we're binding to -- this key would have to change if and only if the ref changed). But this seems like something that should handled in the Firebase library itself, not in ReactFire.

@prescottprue
Copy link
Contributor

For anyone that is still looking for a solution to this, you might want to checkout react-redux-firebase (disclosure: I am one of the authors).

It provides a HOC similar to those proposed above.

@anaibol
Copy link

anaibol commented Aug 5, 2017

React Fire seems dead, is it?

@marcello3d
Copy link

I've switched to https://github.com/unfold/react-firebase

@samtstern
Copy link
Contributor

We have officially deprecated reactfire, as we no longer believe it is the best solution for Firebase developers looking to integrate with React.

Please see the README for information on how to migrate to a better solution. We are working on some new efforts to better serve the React community in the future.

@FirebaseExtended FirebaseExtended locked and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests