Codepath

Components

Components are the building blocks of React. It allow us to have independent, reusable pieces of code that brings composition to the UI layer.

Think of it as Legos for developers. Here are some example components that you might build or source externally:

  • <Navbar />
  • <Header />
  • <Avatar />
  • <Container> ... </Container>

⚠️ React components need to be capitalized. This is how React differentiates between a custom React Component and a built-in HTML element

In a nutshell, components are like JavaScript functions. They accept arbitrary inputs and return React Elements describing what should appear on the screen.

Defining a Component

React Components can be define as both functions and classes. Let’s start with the simplest and most up-to-date: a functional component via JavaScript function:

function Header(props) {
  return (
    <div>
      <h1>Hello, {props.name}</h1>
    </div>
  );
}

You will also see components being defined as JavaScript classes:

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

💡 React Hooks, introduced since React 16.8, drastically reduces the need for creating class based components and encourage developers to create functional components that creates and manages their own state.

You may see the old style (using classes) within React’s official documentation. They are working on updating to using Hooks in their beta docs.

Passing & Accessing data

To allow code composition, components can take in parameters, called props (properties), as well as any children elements as a single object to pass in data. Think of components props as arguments to a function.

Passing data to a React Component looks very similar to defining attributes to an HTML element.

<Header name="CodePath" />;

The code above renders “Hello, CodePath” on the page as we are passing the name prop to the Header component.

// Header Component
function Header(props) {
  return <h1>Hello, {props.name}</h1>;
}

Each prop that get’s passed to a component is added as a key on the props object. Bear in mind, you can pass any type of Object as props. This mean, you can pass components as props as well as functions or if nothing is passed, props will be an empty object.

<Profile 
	name="CodePath" 
	username={<code>@codepath</code>} 
	onFollow={() => handleFollow()} 
/>;

Passing props is how data flows from parent to children in React apps as it adhere to the Unidirectional data flow. That said, they must follow one single rule: Never to modify it’s own props. All React components must act like pure functions with respect to their props.

Consider the following function, which is considered “impure” as it changes it’s own input

/**
 * AddToNumbers
 *
 * @param {Array<number>} numbers
 * @param {number} newNumber 
 * @return {Array<number>}
 */
function addToNumbers(numbers, newNumber) {
	numbers.push(newNumber);
	return numbers;
};

In contrast, take a look at this version of the function which is “pure” as it does not attempt to change the input.

/**
 * AddToNumbers
 *
 * @param {Array<number>} numbers
 * @param {number} newNumber 
 * @return {Array<number>}
 */
function addToNumbers(numbers, newNumber) {
  const numbersCopy = array.map((n) => n);
	numbersCopy.push(newNumber);
	return numbersCopy;
};

Component Lifecycle

The following diagram shows React Component most common Lifecycle methods. This methods cover the vast majority of use cases you will encounter when dealing with React Components. They are described in more detailed in the table below

React lifecycle Methods Diagram https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

Lifecycle Method Description Uses
constructor() The constructor is called before it is mounted. You should call super(props) before any other statement - Initializing local state by assigning an object to this.state.
- Binding event handler methods to an instance.
render() The render() method is the only required method in a class component. It should be a pure function. Typically returns a React Element created via JSX
componentDidMount() The component is mounted (inserted into the DOM tree) Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
componentDidUpdate() This get’s triggered immediately after an update occurs. This method is not called for the initial render To operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props
componentWillUnmount() Runs before a component gets unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount()
Fork me on GitHub