⚠️ This lesson is retired and might contain outdated information.

Building a React.js App - ES6 Refactor: Firebase and React Binding with re-base

Tyler McGinnis
InstructorTyler McGinnis
Share this video with your friends

Social Share Links

Send Tweet
Published 9 years ago
Updated 6 years ago

In this lesson, we’ll finish refactoring our application to ES6. Along the way, we’ll learn how to get route parameters in React Router without mixins as well as learn about re-base, a library for building React applications with Firebase in ES6

Boris LOUBOFF
Boris LOUBOFF
~ 9 years ago

Hi, first of all, thank you for this great serie !

I have a question about the way to replace mixing with ES6. Tyler showed us how to deal with it using contexts. With the upcoming feature of ES7 (with the babel?stage=0 setting in the web pack config), could we use the "@" syntax ?

For example : import React from 'react'; import Router from 'react-router';

@Router class Profile extends React.Component { ... }

What I understood about the "@" syntax is that it allows us to attach some methods of the Router object on our current Profile class (but without inheritance). Am I right ?

Thanks. Boris.

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

Hi Boris.

You are correct. What you're describing is called decorators. I don't have much experience with them yet so I didn't include them in the series (and it was an ES6 refactor not ES7). For more info, check out this link. https://github.com/rackt/react-router/issues/1173

Kasper
Kasper
~ 9 years ago

Thanks for the series! It really made a huge improvement for me personally, to get a better grasp on both React and also ES6.

I may have missed the point somewhere along the line, but I'm a bit baffled about how/why we don't have to 'import react-router' and how it just suddenly appears to be working after setting the contextTypes object.

I hope you can help me out with this. :-)

Best regards, Kasper

Boris LOUBOFF
Boris LOUBOFF
~ 9 years ago

Hi Tyler, thanks for your reply.

Boris.

David
David
~ 9 years ago

Thanks for a great series. A lot of concepts that I'd half-grasped have now been clarified.

Would be great if you extended this out to incorporated a flux based model ;)

Thanks again, Dave.

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

Thanks David! If no other instructor gets to Flux in the next few weeks I'll go ahead and extend the series.

Aaron Kenez
Aaron Kenez
~ 9 years ago

Thanks for the amazing series Tyler. I am confident I will be able to get my own demo project going now after watching this! I would also be interested in seeing how using Flux could improve the GitHub note taker app.

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

Thanks Aaron! I like the idea of adding Flux as well. Hopefully I'll get to it soon.

Simon Davies
Simon Davies
~ 9 years ago

Great series, first off the whole react one showed me more here than trying to figure things out, just what i was looking for a good example of how to use and see react in a working example.

Then into ES2015, just took it to the next level. This series opened my eyes even more to react.

welldone.

PS: Flux too please :-)

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

Thanks for the kind words Simon.

Henry
Henry
~ 9 years ago

Great series, well-presented! Thanks for making this available.

Daniel
Daniel
~ 9 years ago

Thanks so much for the series, Tyler. I'm a lot more confident in putting pieces of a react app together now. Please post more tutorials in the future about these integration-y concepts! There are not many series that focus on best practices in piecing together parts of a live application!

Philip Cox
Philip Cox
~ 9 years ago

Great job on the series Tyler, it's a nice extension to your blog post! Thank you.

Philip Cox
Philip Cox
~ 9 years ago

Hi Kasper. I hope I am correct, I believe we have access to react-router in all of our child components because we passed down the properties of react-router as props in App.js with the use of the spread operator {...state}. Hopefully Tyler can clarify this.

Thorben
Thorben
~ 9 years ago

Hi, I was wondering how I can use can use re-base together with React-Natives's ListView component.

This is what I am trying to achieve:

this.ref = base.bindToState('items', { context: this, asArray: true, state: 'items' }); this.setState({ dataSource: this.state.dataSource.cloneWithRows(this.state.items),

})

My problem is that the "this.state.items" is still empty when it is passed to the datasource state. What is the best way to fix this?

Thanks

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

You have a few options. What I usually do is remove setting the dataSOurce on the state and instead just cloneWithRows in render. Something like this.

render(){
	return (
 		<ListView
	      dataSource={this.dataSource.cloneWithRows(this.state.items)}
 	      renderRow={this.renderRow}
	    />       
    );
}

I also wouldn't put dataSource (new ListView.DataSource...) on the state but move it to just being a property on the class.

Thorben
Thorben
~ 9 years ago

Thanks a lot, this did help.

However I am now getting stuck with other issues:

  1. How can I delete an item with syncedState? I was able to do it before with Firebase.remove(), but I struggle to do it with Rebase.

  2. How can I use Rebase with two different instances of the same components? E.g. I have two instances of a components showing the same list, where one of them is filtered. I am getting an Error saying "REBASE: Endpoint (items) already has listener syncState" when switching to the second component

  3. How can I implement a loading spinner? Is there a callback I can use to stop my spinner with this.setState({loaded: true}) once the data is loaded?

Thank you Tyler! I would also really appreciate if you could provide short code snippets in your answer.

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago
  1. You do it the normal way you would delete an item in React, usually using .splice.

  2. Currently you can't do this. There's an issue filed right now for this feature.

  3. Not for setState. There's an issue for this as well.

Thorben
Thorben
~ 9 years ago

Thank you!

Regarding #2) I guess that is the same issue with base.listenTo? (even though I use them in different components)

My goal is to make each Component a "Mirco-MVC", wich deals with its data needs in isolation. (Inspired by this article: https://medium.com/@AdamRNeary/unidirectional-data-flow-yes-flux-i-am-not-so-sure-b4acf988196c)

Am I correct if I assume that this is not possible with re-base today? Whats your take on the Micro-MVC approach?

Update: Is there a way to shut down the base.listenTo on componentWillUnmount? base.reset(); didn't work for me, but maybe I am doing it wrong.

Nils
Nils
~ 8 years ago

Super good series ! knew nothing about react before. Now maby i like it more than Angular. But i have not checked out Angular2 yet so thats next on the list :)

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Thanks for the kind words! Glad you enjoyed it. I've heard great things about NG2 so definitely check it out as well.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Sorry for the slow response. The return value of listenTo is "An object which you can pass to removeBinding when your component unmounts to remove the Firebase listeners." That should be what you're looking for.

Brent
Brent
~ 8 years ago

Just finished this series. I struggled a little bit at times because I installed all the current modules, but I feel like it was actually good for me. I learned a lot about react, as well as the community and how fast it's moving. Anyway, thanks for putting so much time into making the best React tutorial I've seen!

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Thanks so much for the kind words, they mean a lot. I'm glad you challenged yourself a bit with the latest modules. The React world is fast moving so you're definitely better off for it as you mentioned. Congrats again and if we're ever at the same conference or event flag me down.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Kasper!

Thanks for the kind words. So React Router has actually moved away from the contextTypes magic and in the newer version (which I'm currently updating the videos to), you import react-router as you'd expect.

To answer your questions though, contextTypes in React allow you to pass some piece of data down to any component that needs it, that sounds more useful than it actually is. It's not used very often but it is sometimes used at the Library level (like React Router).

egghead eggo
egghead eggo
~ 8 years ago

The lesson video has been updated!

Igor
Igor
~ 8 years ago

Are there any tests or test frameworks included in this starter?

Igor
Igor
~ 8 years ago

Are there any tests or test frameworks included in this starter?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

To focus entirely on React I chose to leave out testing. I know there's an egghead React testing series in the works currently though.

Alan Eng
Alan Eng
~ 8 years ago

Many thanks for this series! I've worked my way about halfway through and am really enjoying it so far. Question -- I understand this has all been done locally even without a local web server. How can I go about deploying this app to my local web server and eventually to the web? Or is there a cast you can recommend that demonstrates how to develop on localhost and deploy to the web?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Alan,

That's a great question. I don't now of any screencasts currently that do this but if you're used to deploying apps to servers it will be relatively the same experience. I'm planning on adding more videos to this series soon (Redux, Functional Components, etc) and I think it would be a great idea to have the last video be all about deploying. Thanks for the tip!

Tyler

Vivek Agarwal
Vivek Agarwal
~ 8 years ago

all working fine. but just the notes part. I am getting this error: Failed propType: Invalid prop notes of type object supplied to Notes, expected array. Check the render method of Profile.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Vivek. Are you using asArray: true when you're using Re-base? Basically what that warning is saying is that your Notes component expects to receive notes as an Array, but it's receiving notes as an object.

Andreas
Andreas
~ 8 years ago

I run into the same problem with nasty errors in the console when looking up a new github user. Got rid of the errors by making sure it's an array coming in: {notes.constructor === Array && notes.map ....

Maximilian Patan
Maximilian Patan
~ 8 years ago

There's a spelling error here and in the github repo - asArrray: true

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Ah good find. I fixed the Repo.

Maximilian Patan
Maximilian Patan
~ 8 years ago

Hi Tyler - I'm seeing an issue where the notes section seems to be one state behind the other data. So on initial load, when loading data for the first user (user-a), all works well. However, if I change the username (user-b), the github info changes but the note data still shows user-a info. If I search for user-b again, then the note data changes.

Do you see this behavior? Still trying to track this down. If I find the issue I'll post an update.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Check that your shouldComponentUpdate code is the same as the one on the Repo (and if it is, check all your other code to see what's different).

Maximilian Patan
Maximilian Patan
~ 8 years ago

Hmm - unless I missed this, I don't think we handled shouldComponentUpdate in the tutorial. What module would this be in?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

I said shouldComponentUpdate but I meant, componentWillReceiveProps. My bad. Here's what it should look like. https://github.com/tylermcginnis/github-notetaker-egghead/blob/master/app/components/Profile.js#L22-L25

Phu Nguyen Anh
Phu Nguyen Anh
~ 8 years ago

Hi Tyler, I got the same problem as Maximilian Patan. I've checkout your code from github and run it and still got the same problem.

~ 8 years ago

I am having this same issue as well. I copied the EXACT code you have in github at the branch for this lesson (also as you have linked above) and the behavior we're all seeing hasn't changed.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Alright I'll check it out. Thanks for the heads up everyone!

~ 8 years ago

Ah, and I have just now cloned your repo, and checked out the lesson 16 branch, and am getting this same behavior that three of us are reporting where the notes seem to be out of sync with the github account until you refresh the page.

Can you please address this for us? Thanks!

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Yup. Looking at it right now.

~ 8 years ago

I figured out what's going on.

In Profile.js in the init method, you were binding to props.params.username instead of the username passed into the init method. When I change line 30 to just use the passed in username, things work as expected!

~ 8 years ago

I've learned a lot going through this tutorial. Thank you for making it!

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

You're very welcome. Also, nice find! Thank you! I'll fix the repo and hopefully get an updated video out soon.

Gleb MIkheev
Gleb MIkheev
~ 8 years ago

Video is not loading for now(

Dave Dawson
Dave Dawson
~ 8 years ago

Thanks for this tutorial, and for writing re-base! I'm able to understand and apply everything here and in the re-base docs without a problem.

But I'm having trouble understanding how to use re-base to join two Firebase tables. Is that possible?

Mr. Outis
Mr. Outis
~ 8 years ago

Hi! Can you upload a video about how to deploy this app?

Richard
Richard
~ 8 years ago

Thanks for the tutorial.

Quick question: I create a ref to my my user object in firebase using firebase in my Main.js and would like to use that ref on an edit details page. Can I pass that user ref as a prop in the routes.js? I am currently getting an error that is saying "Uncaught Error: REBASE: Endpoint (users/1) already has listener syncState"

Richard Hess
Richard Hess
~ 8 years ago

i was able to use reactfire with the es6 classes by utilizing the react-mixin project

import reactMixin from 'react-mixin'; import ReactFireMixin from 'reactfire';

// call this outside the Profile class definition reactMixin(Profile.prototype, ReactFireMixin);

Sonar
Sonar
~ 8 years ago

no transcript ?

Andrey
Andrey
~ 8 years ago

When I've been trying to use re-base for the first time, I've got such error in Chrome console:

REBASE: Rebase.createClass failed. to migrate from 2.x.x to 3.x.x, the config must be an object. See: https://firebase.google.com/docs/web/setup#add_firebase_to_your_app

To resolve this you need to change the Rebase.createClass({}) call, like this:

const base = Rebase.createClass({ apiKey: "", authDomain: "", databaseURL: 'https://reacttest.firebaseio.com/', storageBucket: "" });

Kylan Hurt
Kylan Hurt
~ 7 years ago

Yeah I am having the same issue with the rebase versioning. Should we point our package.json at a specific version of rebase?

Edit: Nevermind, downgrade to version 1.5.1 for rebase from within your package.json then run npm update from your command line.

Sarah Craig
Sarah Craig
~ 7 years ago

When using rebase with your firebase URL I get the error:

bundle.js:17109 Uncaught Error: REBASE: Rebase.createClass failed. Expected an initialized firebase database object.

Przemysław
Przemysław
~ 7 years ago

The same is in my case. I have config with all credentials etc which was passed to Firebase and now it looks like a configuration is missing.

Update : I did such thing and it started to work:

//(please change **** to yours credentials etc)

import Rebase from 're-base'; import firebase from 'firebase';

var app = firebase.initializeApp({ apiKey: "", authDomain: ".firebaseio.com", databaseURL: "https://*****.firebaseio.com", storageBucket: "**********.firebaseio.com" });

const base = Rebase.createClass(app.database());

Markdown supported.
Become a member to join the discussionEnroll Today