An Introduction to React

A quick primer

## Starting Off

If you aren't familiar with Javascript or want to make sure to fill in the gaps, read through this javascript primer from MDN: [Javascript Basics](https://developer.mozilla.org/en--US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)

This content is inspired by the React [docs](https://reactjs.org/docs/getting-started.html).

## What is React?

At the highest level, React is a Javascript library that is the "View" in the MVC (model/view/controller) pattern.

React components allow you to represent your application data in a tree of components.

Your entire app could be a giant tree of components or you could have mini-component trees in various parts of your existing application.

## WRITING COMPONENTS

Each component in your apps tree is written using a special extension to the javascript language called JSX. JSX stands for Javascript and XML and once you get the hang of it, it is really nice! The syntax can turn off some folks initially, but in time you get used to it. Dive more into JSX in the docs [here](https://reactjs.org/docs/introducing-jsx.html).

What does it look like?

```js

<SomeJSXElement>Hello World</SomeJSXElement>

```

In order to make this work, Facebook took advantage of a tool called [babel](https://babeljs.io/) and created a plugin that transforms JSX into regular old javascript that a browser can understand.

So, you write this:

```js
<SomeJSXElement>Hello World</SomeJSXElement>
```

And babel transforms it into this:

```js
React.createElement(SomeJSXElement, null, "Hello World");
```

There is nothing stopping you from writing all your React using `React.createElement(...)` however it will be painful and is generally not recommended.

## Props vs State
Components don't do much without having some sort of properties set or some local state.

Here are some general rules when it comes to props vs state:

- Props are passed down the component tree.
- State is localized to the component it is used in, but can also be passed down to child components as a prop.
- Global state is achieved through Context, which we will discuss later.

## Example

### Props

In the example below, "name" is considered a prop of the "MyComponent" component.

It is passed to the component like so:

```js

<MyComponent name="Sarah" />

```

If you want to update a prop, you'd typically also pass a function to your component that would provide the new value for the prop. For example:

```js

<MyComponent name="Jim" updateName={updateName} />

```

### State

"favoriteColor" is considered state and is updated by calling the "setFavoriteColor" function.

- You might update it after clicking a button or typing into a textbox.

```js
const MyComponent = ({ name }) => {
 // This is using array destructing
 // The default value for "favoriteColor" will be "Green"
 const [favoriteColor, setFavoriteColor] = useState("Green");

 return (
   <div>
       Hi {name}!  Your favorite color is {favoriteColor}.
   </div>
 )
}

MyComponent.defaultProps = {
 name: "Foo"
}

MyComponent.propTypes = {
 name: string
}
```

### Designing Components

When beginning to design a component or an entire page in React it is helpful to approach things using this technique:

- Whiteboard or write up static HTML first
- Decide where it makes sense to extract your components given the UI
- Consider what props or state each component will need:
- Pay attention to…
 - Shared props
   - What props are needed across multiple components?
   - Does it make sense to keep track of these props in the parent component or is something that should be in context? Usually parent component is the best place to start until you need it else where.
 - Local state
 - What can be localized to the component?
- Create your components
- Make sure to add your propTypes and defaultProps

Read more about this strategy [here](https://reactjs.org/docs/thinking-in-react.html)

## FUNCTION VS CLASS COMPONENTS

There are generally two approaches to writing components; function components or class components. Both are valid ways to express React components.

Class components are a great way to learn, however there is a movement towards using Function components and hooks, so that should be the focus. There are exceptions, such as ErrorBoundary components that must be class based, but otherwise, it is recommended to use function components.

## Examples

### Function Components

There are a couple ways to express function components. All of these are the same, just different ways of doing things.

Using a fat-arrow function:

```js
const MyComponent = ({name}) => {
 return (
   <div>Hello, {name}</div>
 )
}
```

This can actually be even cleaner, which is sometimes why the fat-arrow function is preferred:

```js
const MyComponent = ({name}) => <div>Hello, {name}</div>
```

Using a named function:

```js
function MyComponent({name}) {
 return (
   <div>Hello, {name}</div>
 )
}
```

### Class Components

```js
class MyComponent extends React.Component {
 render() {
   return <h1>Hello, {this.props.name}</h1>;
 }
}
```

## Lifting State Up
No matter how much design you do up front, one will inevitably run into a scenario where more than one component needs access to some local state.

In this case, you will want to lift your state up the component hierarchy so you can pass the state back down as "props".

The React docs explain this quite well [here.](https://reactjs.org/docs/lifting-state-up.html)

## Global State

There are times when you will need to access something deep down in the component tree and also at the top. Rather than passing those props down through the component tree (called prop drilling), you can use "context".

To use context...

- You must first create it.
- Then you provide the context to your components by wrapping them in a "Provider"
- You then gain access to context by using the useContext hook

Read more [here](https://reactjs.org/docs/context.html)

## Example

```js
// Create context
const MyContext = React.createContext();

// Provide it to your app using a Provider
const App = () => {
 const [theme, updateTheme] = useState();
 
 return (
   <MyContext.Provider value={{ theme, updateTheme }}>
     <Container>
       <Header />
       <Content />
       <Footer />
     </Container>
   </MyContext.Provider>
 )
}

// Then, let's say down in your <Content /> component you want
// to access the theme:

const Content = () => {
 const { theme } = useContext(MyContext);
 
 return (
    <div>
      You are using the {theme} theme!
    </div>
 )
}
```

## Hooks

A fairly recent update to React was the introduction of hooks.  These are simply special functions that start with "use", abide by some rules and allow you to do things in function components that were previously achieved via higher order components or class components.

Let's take a look at a few common hooks.  If you are eager to dive in, check out the docs [here](https://reactjs.org/docs/hooks-intro.html)

### useState

Any time you want to keep track of something that you will be changing over time and want to tell React to re-render when it changes, you'll use the `useState` hook.

Read more [here](https://reactjs.org/docs/hooks-state.html)

**Example**

```js
const [name, setName] = useState("Jim")
```

### useEffect

Any time there is some sort of side effect, you'll want to use a `useEffect` hook.

Read more [here](https://reactjs.org/docs/hooks-effect.html)

**Example**

```js
// This will run every render
useEffect(() => {
 console.log("I ran!")
})

// This will run every time the "loading" prop changes
useEffect(() => {
 console.log(loading)
}, [loading])

// This will run every time the "loading" prop changes
// and will also run a function returned from the useEffect
// hook when this component is removed from the DOM
useEffect(() => {
 console.log(loading)
 
 return () => {
   console.log("This is where you can run clean up code!")
 }
}, [loading])
```

## useLayoutEffect

Works the same as `useEffect`, but you'll want to use this if you are doing any sort of measuring of style-related things with the DOM.  Essentially, if you find yourself accessing HTML elements properties like height or width, you will want to use the `useLayoutEffect` hook.

Read more [here](https://reactjs.org/docs/hooks-reference.html#uselayouteffect)

## useRef
Allows you to keep track of something for the lifetime of your component. This is often used to access the native DOM element associated to some JSX element.

Read more [here](https://reactjs.org/docs/hooks-reference.html#useref)

**Example**

```js
const MyComponent = () => {
 const inputRef = useRef(null);
 
 const doIt = () => {
   // Output the background color for the div
   console.log(inputRef.current.style.backgroundColor)
 }
 
 return (<>
   <div ref={inputRef} style={{backgroundColor: "#123"}}>Hello World</div>
   <button onClick={doIt}>Click Me</button>
 </>)
}
```

## Rules of Hooks

There only a couple rules one must abide by in order for Hooks to work in the React world.

1) Hooks must be first


2) Hooks can only be using in function components or other hooks.

Read more [here](https://reactjs.org/docs/hooks-rules.html)

## Render and Portals

There are a couple ways to render React components.  The most common way in the web-world is to call `react-dom`'s `render` method.  The other way is by using a `portal`, which allows you to basically inject a React component anywhere in your site.

Sometimes you aren't working with a 100% React application.  For example, if you are working on a WordPress site where you want to use React for a dropdown menu at the top of the page and a specialized store locator tool.  This is where you'd want to lean on React's `portal`.

Read more [here](https://reactjs.org/docs/portals.html#gatsby-focus-wrapper)

## Mapping Data and Keys

Often times you will be displaying a list of things.  If you find yourself using `map`, make sure to provide each item with a `key`.

Read more [here](https://reactjs.org/docs/lists-and-keys.html#keys)

Example

```js
data.map(item => <li key={item.id}>{item.label}</li>)
```

## Odd HTML Attributes

One oddity of React is that they had to slightly adjust some HTML attributes in order to have it jive with the ones already established for native HTML elements.

**Some examples:**

- Rather than `<div class=...`, you'd use `<div className=...`
- Rather than`<button onclick=...`, you'd use `<button onClick=...`
- Rather than`<label for=...`, you'd use `<label htmlFor=...`

Be on the look out for these!  There are only so many and if you do happen to make a mistake, React is pretty good about yelling at you in the console.  So, be sure to pay attention to those console warnings!


## More Advanced Topics

- [Intro to React Tutorial](https://reactjs.org/tutorial/tutorial.html) - This React tutorial will help solidify what we covered above.
- [Explore more React](https://reactjs.org/docs/hello-world.html) - There are many other aspects of React not mentioned above, so if you would like to explore other areas, feel free to peruse.
- [Create React App](https://create-react-app.dev/docs/getting-started) - This is the defacto standard for creating new React apps.  This is where you want to start if you want to quickly get going with your very own React app.
- [Redux](https://react-redux.js.org/introduction/basic-tutorial) - This is a common library used to keep track of your application state in "stores".  It is an essential ingredient in many React apps and although you may not need to use redux all the time, it is important to understand the concepts of reducers, stores and actions.

## Frameworks

- [NextJS](https://nextjs.org/) - React is considered a library, where as Next.js is considered a framework.  There are many rules and conventions that Next.js has adopted and although it is overwhelming to try and just learn Next.js, it is helpful to at least be aware of it and know when you might want to use it.
- [GatsbyJS](https://www.gatsbyjs.com/) - Another React framework for building static web sites.  This is great for blogs and many other sites.  The learning curve here is steep, similar to Next.JS, so take it slow and this is another to be aware of in the case where it makes sense for you to use.
- [Remix](https://remix.run/) - Yet another React framework.  This framework does cost money to use, but if you are looking to get going fast with a robust framework, this may be it.