Skip to content

Instantly share code, notes, and snippets.

@neosaurrrus
Created August 22, 2018 14:01
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 neosaurrrus/975293daaf37b20f359463084c413589 to your computer and use it in GitHub Desktop.
Save neosaurrrus/975293daaf37b20f359463084c413589 to your computer and use it in GitHub Desktop.

Introducting React Concepts

After playing around with with a RESTful application, I decided it was time to learn a different way of doing things. Enter React which you might have heard about.

I have been learning from various sources the main ones are:

Stephen Grider's Modern React with Redux Wesbos' course React for Beginners

Stephen I think is great at introducing concepts and explaining them. Wes takes you through the end-to-end process in a 'real life' way with some helpful tips along the way.

This first post is just a summary of some of the key parts of React, and explore some newbie errors before we go into using them in anger.

By the way,make sure you have a good grasp of ES6 before getting into React for two reasons:

  1. The syntax will make more sense
  2. Things you may think of as part of React are really just leveraging whats already in ES6.

The Building Blocks of React

Before we get into building something cool, we need to understand some core concepts of React:

  • Setting up React
  • JSX
  • Rendering
  • React Application Structure
  • Imports and Exporting Components
  • Components
  • State

How do we set up React?

In short, you don't.

In slightly longer, setting up React can be complicated. Create-React-App is one tool that makes it easier to develop a React app. We can eject from when we are production ready but that's a topic for later on.

Both Stephen Grider and Wes Bos recommend a pre-configured environment to get familar with React first so that's what I did.

JSX : What is it and how can it show stuff on the page?

JSX is a way introduced in React of writing easily legible HTML in a otherwise JS file. It isn't technically required but writing in pure JS gets messy fast. One drawback is that JSX doesnt run on a browser by default so we need to make use of Transpiling tools, namely Babel and Webpack, to turn it into JS the browser can understand.

The index.js file references a script called bundle.js file will parse your jsx code and bundle it all into one big file with all the magic to make it run.

If you view the source of bundle.js you will appreciate that it's sensible to rely on Create-React-App while you are getting the hang of React itself.

You can make a JSX file as you would any other file in your IDE. But there is a few things to be aware of...

The JSX rendering minefield

Let's take the following JSX example:

https://gist.github.com/4c968d990f5283fa65a14cad878511da

Will it work? No.

Error 1: React is not defined

If we simply do React.render(App). It wont know what React is as the JSX has no reference to it.

To solve this, we ensure we need to explicitly reference React via a module. To do this, at the top we need to add:

`import React from 'react'

In plain english, this means go grab the react package as an object called React. So lets try it again..

Error (well ... warning) 2: React.Render is deprecated. Please use ReactDOM.render from ('react-dom") instead

React used to be one package, however now it is split into several parts because as React has become more popular, all it's features may not apply.

For this we need ReactDOM which is focused on iteracting with the DOM. We need to import that to get rid of the warning:

import ReactDOM from 'react-dom'

and change the render statement to use ReactDOM:

ReactDOM.render(App)

Alright it should work now right?

Error 3: Uncaught error: Invariant Violation: ReacDOM.render(): Invalid Component Element. Instead of passing a component class, make sure to instantiate it by passing it to React.createElement

Yep, still not working…

The 'App' function we used is actually a defined class of component, it cant be added to the DOM, it is effectively a blueprint to create an instance.

We can make an instance by using tags: <App></App>. This can be self closed by doing <App /> instead which gives us this:

ReactDOM.render(<App />)

So maybe one way of looking at JSX is that we can make our own HTML tags that can store data and pass it to each other. Anyhow, it has to work now right?!

Error 4: Target container is not a DOM element

Ok, so this is quite straightforward. The render method needs a RENDER TARGET, a place in the DOM to put the React application. To do this, there is a second argument we need to add. For this example, we will say there is a div in our HTML with the class "container".

https://gist.github.com/064f4a71b52fa3b9761855544dea22ee

And now….. it will work! So there better be a good reason for going through all that effort right?....right?

React Application Structure

A good react app is split into self-contained, non-code repeating snippets called Containers.

There is a little bit of Art to determine how to split things into components but one key rule is One Component per file This allows a clear speration of concerns, a team of developers can focus on a particular component in a relatively safe way.

An example a video player app might consist of components for:

• Search,
• The Video player
• Video Details
• An unordered list of other videos
• Items within that list.

You will want a container component to keep them all within which is traditionally defined as index.js. The rest can typically kept in a components folder.

Here is an example file structure of what I mean:

-src
    - index.js
        - Components
            - search_bar.js
            - video_detail.js
            - video_list_item.js

But like I say, it’s a little bit of an art that depends on what you are doing, just aim for clarity and consistancy whatever you do.

Importing and Exporting Components

Once you have your JS files containing a component, how do you use them? First make sure your component file has the following:

  1. Import React (and other dependancies)
  2. Write your component in a function
  3. Export the function using the following line: export default <component>

In your Index.js, import the component as you would with any other package:

import <component> from <file reference><js file>

Don't forget the file reference, in the video player example above the import file will look like:

https://gist.github.com/934a30a518a655e5aa6d1b298a8a2cf6

Now we can add the component in Index using JSX tags: <videoPlayer />

The two types of Components

If we step back, we have thus far created components that are functions like:

https://gist.github.com/85e9df1610de55ac687e7d3d9a994c68

This is a functional component. It is a component that just spews out JSX. When more internal logic and decision making is required, e.g event handling, we use class-based components. This uses Es6 classes like so:

class Search extends React.Component { }

When we use classes we still need it to output JSX, we do this via adding a Render Method:

https://gist.github.com/14f1f9a4553a61e54067de30e5494343

Put simply, use functional components for simple stuff that renders out, class-based components for extra smarts.

A simple way of handling an event in a Class-based component

There is two steps to do this:

  1. Declare an event handler - something that is ran when the event happens

  2. Pass the event handler to the element we want to monitor the event.

Something like this:

https://gist.github.com/c95be8ac4f1cfeefc48c201a4b757eca

The react docs explains more about different events.

This is where State comes in

State is one of the hardest things to understand about React

State is a plain Javascript object that is used to record and react to events. Every class-based component has a state object and a change to state causes the component to rerender plus any children.

To use state we first we need to initialise:

https://gist.github.com/2d952fdc7c874a3e132c4e8c34422f3f

Second, we can change the state by using the setState method:

https://gist.github.com/da7d3eca13a1583a62941338ad946742

Always use the setState method, do not manually update the state object, else react wont know about the change.

Why do we do this?

Since state updates when it sees a change, the properties of the state object are good to use in the render method:

https://gist.github.com/43bf0e8e331022c4eac1ce5a2d4d912a

This will result in a display that automatically updates as the user makes changes

This is cool! However this is not the right way around. The Input controlls the state. However the input should be updated by the state, so how do we do that?

Proper Controlled Components

In this technique, the state controls the value of element. It is best shown first…

https://gist.github.com/c6febec198eed388a4083370bf539c89

The sequence of events is now different:

  1. when the component is rendered for the first time the state tells the input what its value is, which is probably blank.

  2. When the user triggers the event, the event causes setState to update the searchTerm in state.

  3. The change of state causes the component to rerender which then changes the value to whatever it is in State.

It's the Circle of State, you can add your own Lion King GIF here.

Conclusion

So that's the first key concepts of React, we will talk about them some more and encounter new ones as we go into using them in anger.

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