View on GitHub

react

React[0] + Redux[0] > A brief introduction to React and Redux

Components

We use components to split our UI into reusable “blocks” that can receive props (aka, read-only data), hold state (aka, mutable data) and return, as we saw earlier, React elements.

Note: Remember that props are inputs to Components. We pass them from parent to child. This is the unidirectional data flow pattern.

You should name your component following the PascalCase (sometimes called UpperCamelCase) convention — i.e. each word starts with a capital, including the first one.

Example: <ListOfRecords />. Intrinsic DOM elements are written in lowercase (<div>, <section>, <input> …) — that’s how JSX tells them apart from components. Use camelCase (sometimes called lowerCamelCase) for HOC/HOF, methods, event handlers (onClick, onSubmit) and prop names in general.

Note: Some people also name functional components following the camelCase standard, but, once they import them they rename them switching to PascalCase. They keep the filename with PascalCase

Example:

Item.js

const item = () => 'This is an item'
export default item

ListOfItems.js

import Item from './Item'

const Items = () => <Item />

In react we have 2 types of Components:

In relation to paradigm

  1. Class components (pseudo Object Oriented Programming)
  2. Functional components (Functional Programming)

In relation to internal or local state

  1. Stateful components
  2. Stateless, pure or presentational components (with no state management)

Before React 16.8 (aka, before Hooks), functional components were not able to hold state. Be particularly aware of this if you are following an outdated tutorial or working with “legacy code”.

Class Component

import React, { Component } from 'react';

/* Or, if you don't 'destructure' 
class App extends React.Component {}
*/
class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello World!</h1>
      </div>
    );
  }
}

export default App;

Note: Class components require render() method.

Functional Component

Regular JS functions that return a React element or Component.

Example: pre ES6

function App() {
  return (
    <div className="App">
      <h1>Hello World!</h1>
    </div>
  );
}

Example: ES6 (…with implicit return)

import React from 'react';

const App = () => (
  <div className="App">
    <h1>Hello World!</h1>
  </div>
);

export default App;

Functional components are the recommended default for new code since the release of Hooks (React 16.8). The reasons are not raw performance — the React team has explicitly said function and class components have similar runtime cost — but rather: less boilerplate, no this-binding edge cases, easier composition, and access to the Hooks API (useState, useEffect, useMemo, custom hooks, etc.).


Quick note about return.

Each component must always return “something”: JSX, plain JS Data Types like number, string, array, or “null” if we explicitly “don’t want to return”. You cannot avoid the return statement or “return implicitly”: return;.

All these (among others) are valid returns:

As you can see, we are always returning one MAIN or root element. Note: an array is a collection of elements, but ONE element in essence.

However, if you try something like…

return <div>1</div><div>2</div>

… you will see the following error: Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?.

This is happening because React expects just one root element (and within it, zero or multiple adjacent children).

There are several ways to fix it…

  1. Wrap everything within a parent/root element (example: div) IMPORTANT: With this solution you will have an extra div in your markup, which could force you to have to override default element’s behavior or styling for “presentational purposes”.
    return <div><div>1</div><div>2</div></div>
    
  2. Create a HOC (Higher Order Component) returning what we are passing as children

    Notes:

    • This HOC will just wrap our component.
    • Children will be “whatever” we pass between the opening and closing tags: <Wrapper>...</Wrapper> ```javascript const Wrapper = props => props.children;

const App = props => { return <div>1</div><div>2</div> }


3. Use *React.Fragment*
```javascript
return <React.Fragment><div>1</div><div>2</div></React.Fragment>

In the solution #2 we used a HOC

If you checked our intro, and particularly, the appendix Higher Order Functions, probably you can guess what HOC refers to: a component that takes another component as parameter and returns a new component.

There’s another way of creating and utilizing a HOC: a regular JS function that takes a component as parameter and returns a functional component.

import React from 'react';

const App = props => {
  return <div>Hi!</div>
}

const withWrapper = ComponentToWrap => {
  return props => {
    return (
      <React.Fragment>
        <h1>Welcome!</h1>
        <ComponentToWrap {...props} />
      </React.Fragment>
    )
  }
}


export default withWrapper(App);

When should you use this approach…? Whenever you want to execute some kind of logic. For dealing with plain markup or JSX, you can opt for the previous approach.

IMPORTANT: Be sure to spread the props <ComponentToWrap {...props} /> to avoid issues (not applicable for this example since we are not passing>receiving>rendering props).


Composition

One of the key aspects of React is Composition. Following this logic, we can have -multiple- small components as part of the JSX (or output).

Example:

const App = () => (
  <div className="App">
    <h1>Hello World!</h1>
    <IntroComponent />
    <LanguageComponent default="en" />
    <ContactComponent />
  </div>
);

Remember that small components contribute to the re-usable nature of React and its compositional view. However, try to avoid being extremely granular and always preserve the logic’s context and usage. Example:

Nevertheless, we are not going to dissect the door-lock until we have screws, metal, plastic and paint… Even when (for example) screws are going to be used in several elements.

Think of elements as words and components as phrases.