This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

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

7:37 React lesson by

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

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

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.

Avatar
Boris

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.

Avatar
Tyler

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

In reply to Boris
Avatar
Kasper

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

Avatar
Boris

Hi Tyler,
thanks for your reply.

Boris.

In reply to Tyler
Avatar
David

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.

Avatar
Tyler

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

In reply to David
Avatar
Aaron

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.

In reply to Tyler
Avatar
Tyler

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

In reply to Aaron
Avatar
Simon

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 :-)

Avatar
Tyler

Thanks for the kind words Simon.

In reply to Simon
Avatar
Henry

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

Avatar
Daniel

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!

Avatar
Philip

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

Avatar
Philip

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.

In reply to Kasper
Avatar
Thorben

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

Avatar
Tyler

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.

In reply to Thorben
Avatar
Thorben

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.

In reply to Tyler
Avatar
Tyler

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.

In reply to Thorben
Avatar
Thorben

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.

In reply to Tyler
Avatar
Nils

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 :)

Avatar
Tyler

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

In reply to Nils
Avatar
Tyler

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.

In reply to Thorben
Avatar
Brent

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!

Avatar
Tyler

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.

In reply to Brent
Avatar
Tyler

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).

In reply to Kasper
Avatar
egghead.io

The lesson video has been updated!

Avatar
Igor

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

In reply to egghead.io
Avatar
Igor

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

In reply to egghead.io
Avatar
Tyler

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.

In reply to Igor
Avatar
Alan

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?

In reply to Tyler
Avatar
Tyler

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

In reply to Alan
Avatar
Vivek Agarwal

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.

Avatar
Tyler

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.

In reply to Vivek Agarwal
Avatar
Andreas

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 ....

In reply to Vivek Agarwal
Avatar
Maximilian Patan

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

In reply to Tyler
Avatar
Tyler

Ah good find. I fixed the Repo.

In reply to Maximilian Patan
Avatar
Maximilian Patan

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.

Avatar
Tyler

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).

In reply to Maximilian Patan
Avatar
Maximilian Patan

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

In reply to Tyler
Avatar
Tyler

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

In reply to Maximilian Patan
Avatar
Phu

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.

In reply to Tyler
Avatar

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.

In reply to Tyler
Avatar
Tyler

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

In reply to
Avatar

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!

In reply to Tyler
Avatar
Tyler

Yup. Looking at it right now.

In reply to
Avatar

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!

In reply to Tyler
Avatar

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

In reply to Tyler
Avatar
Tyler

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

In reply to
Avatar
Gleb MIkheev

Video is not loading for now(

Avatar
Dave Dawson

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?

Avatar
Mr. Outis

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

Avatar
Richard

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"

Avatar
Richard

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);

Avatar
Sonar

no transcript ?

Avatar
Andrey

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: ""
});

Avatar
Kylan Hurt

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.

In reply to Andrey
Avatar
Sumit

Hi Tyler, can you redirect me to some resources to understand why is that we cannot use mixins with ES6.

In reply to egghead.io
HEY, QUICK QUESTION!
Joel's Head
Why are we asking?