Skip to content

Instantly share code, notes, and snippets.

@SaraVieira
Created July 6, 2018 10:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SaraVieira/4eb92a552a8094a06e1f2593de3e0763 to your computer and use it in GitHub Desktop.
Save SaraVieira/4eb92a552a8094a06e1f2593de3e0763 to your computer and use it in GitHub Desktop.

React is just JavaScript

Done: No Status: In Progress

Many people starting out get overwhelmed by all the things happening in the React ecosystem. There's this idea that what happens in React is magic and that getting started with React is super complicated unless you use tools like create-react-app .

And honestly, it's not as widely documented that you only need 5 minutes to actually inject React into your page. Dan Abramov has been trying to raise awareness to this and he's been doing an amazing job, so taking from his idea let's make you believe the 5 minutes statement.

But how do I inject React into my application?

Well, first step is finding the files to insert, and these can be found at UNPKG. This is like a giant CDN of all the awesome libraries and frameworks around the world.

If you go to the URL https://unpkg.com/react@16/ you will see all the contents React has and in there you have two folders:

The folder UMD(Universal Module Definition) is the one we want as this one is understood by the browser without any bundler.

You need to also go to https://unpkg.com/react-dom@16/ to get the URL of development version of React Dom as we also need this library to make our project work.

The two links are:

Creating our HTML file

To start we need an initial HTML file. I use VSCode, so here, to create a simple HTML file you just need to type !and then tab and you will have a starter file to insert the two links with script tags. Mine looks like this:

https://gist.github.com/00447809e319edd974bd9b2d0f4215f4

Let's now write some react code!

What is JSX?

JSX (JavaScript XML) may look confusing and magical but in reality it's just some syntax sugar over the React.createElement function. If we don't want any type of npm or webpack magic we can just use this function that has the same effect so let's take a look at it.

Knowing this, we can create a simple div that has some text inside and a class to be styled in CSS, like so:

https://gist.github.com/4800a051e058b6810a14d048d3d15832

If you reload the page, nothing will happen. This is where [react-dom](https://github.com/facebook/react/tree/master/packages/react-dom) comes into play because react itself can be rendered into a lot of places, like native apps for iOS and Android, TV's, PDF and really anything you set your mind to.

react-dom is the library we want in order to render it into the web and then we need the ReactDom.render function. This function takes two arguments:

  • The element we want to render. In this case, that's is our wrapper function
  • Where we want to render it to. In this function you can render it straight into the body but I would always advise to create a new element like a main and render it there. To get this element we will use [document.querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) and pass it our #app.

In code this would look something like:

https://gist.github.com/5ba69cd44608831236a806a953f50599

If you reload the page, you can see our wrapper but it doesn't really look nice so let's add some CSS to it:

https://gist.github.com/9dc745f523780e851c120ca62b9dd4c3

And now you should see something like this when you open your index.html in your browser:

browswr windo

So we got the basics of showing an element and now let's get into some more interactivity by using React's Component State.

Creating some interaction

In this part we are going to create the best App ever. We will get a dog photo from https://dog.ceo/api/breed/akita/images/random, show it on the page, and also add a button to refetch another dog photo. Trust me it's going to be great!

The first thing we need to do is to make our function be a [React.Component](https://reactjs.org/docs/react-component.html) . The main difference for us is that these Components can hold state and the functions can't.

The state contains data specific to this component that may change over time. The state is user-defined, and it should be a plain JavaScript object. - via reactjs.org

We should also consider that if we attach this state to a rendered element, this element will update once the state changes.

For our use case we will need am image property in our state that will have the source for our image. So our Wrapper should look something like:

https://gist.github.com/eb820c32c0591543448a33121e84044c

Wow! So this changed a lot so let's through what is going on:

We now have a class instead of a simple function, you can read more about classes on the Mozilla Developer Docs. We also extend out of React.Component, which means that React.Component is our parent class and we inherit methods from it.

The constructor method is a special method for creating and initialising an object created with a class. There can only be one special method with the name "constructor" in a class. A SyntaxError will be thrown if the class contains more than one occurrence of a constructor method. - via developer.mozilla.org

A constructor can use the super keyword to call the constructor of the super class.

After creating our base class we set the initial state that will be changed with this.state = { image: null }; the reason this is null in the start is because we don't have an image yet. Then in the render function we return the HTML element react will create for us.

Next step is creating the image tag that will have our awesome puppy:

https://gist.github.com/bdd7c58f4bcd061c6cbde4d33ebe710c

We have seen this pattern before when creating our Wrapper component. The only thing we changed here from our Wrapper component is that we now receive an argument with all the props passed to the element. In the props object there is a parameter called source and set that as the src attribute of the image. We also don't pass any children as images don't really have any elements inside them.

Now for the button we do something similar:

https://gist.github.com/e552aa893c23fc1a1637e875fbf59cb7

Here we receive the a function that will be called when this button is clicked and will get another random puppy.

Putting all of this together

We have all the pieces and let's now get this all working together in our Wrapper component by attaching these two elements to the Wrapper class and it's state.

To place these two elements as children of the Wrapper, we need to pass them as the arguments of the React.createElement function. Any argument after the second one will be seen as a children by React.

Our Wrapper will look something like:

https://gist.github.com/8c4d11c08f72cf6903fff07aa93b46b1

Now it's time we actually fetch the image and for that we will use the [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) api provided by most modern browsers.

Let's do that in a separate function and call it when the component mounts on the page:

https://gist.github.com/d31720cb3185bc0f64d5ceba7466c73c

First thing we did was create a getImage function and in that function we get the image. When we got it we called setState, which is how you change the state of a component in React. Assigning the state to a new object won't work because React won't re-render the component.

In componentDidMount we called the getImage function we just created and this will populate this.state.image. That we can pass it to the img element and show our new puppy. We also pass our getImage function to the button so that the user can request a new puppy.

The bind in the constructor is done because functions have their own scope and not the scope of the class it's a part of. When we have a function like this, the value of this is no longer the class methods like setState but it's instead the own function. The this keyword is confusing when you first hear about so you can read more about it in the Mozilla Developer Docs.

We can do two things, we can bind it manually with this.getImage = this.getImage.bind(this) and this will change the scope to be the class. Or we can use arrow functions as these ones have no scope. In this case, for clarity, I decided to go with the first one.

You can see a live version of our awesome website here: https://react-no-jsx.now.sh

Also the code here: https://gist.github.com/SaraVieira/c99fd3ff7177b86c14209df92483f784

I want some magic!

So you want some JSX ah?

I like you! You live on the edge! I would say that to start you can go on the Babel's online playground and play with it a bit. Once you understand it and want to apply to this exercise without much setup you can follow this guide by the react team.

After this you can start playing on codesanbox that offers the whole environment online. Then go ahead and download [create-react-app](https://github.com/facebook/create-react-app) to get React and JSX set up on your own machine.

Conclusion

Hope this cleared some of the magic React sometimes feels to have and got you excited about it. Even if you already know React I hope this has taught you some new fundamentals you might not be aware of.

Go and build dope stuff with React! ⚛️

Thank you to Dan Abramov for bringing this to light!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment