Understanding React Components In Detail

Components are smallest building blocks of any react application. Imagine components as reusable pieces which has its own state, template to render and access to props for accessing data passed to it.

Component in React

A component can be a function or a class which returns a HTML/JSX  expression. Every react component should return a new object of React.createElement.

In react, we can create component in 2 ways:

  1. Functional components
  2. Class components

  • Functional Components

    • They are simply created using functions
    • They are useful when we want to isolate state management from the component
    • Only use them for UI representation
    • Also called as presentational or dumb or stateless components

    •   import React from "react"; //importing React module
        import ReactDOM from "react-dom"; //importing ReactDOM module

        //Functional Component
        function Greetings() {
          //return JSX expression
          return <h1>This is Hardik, this is my first component!</h1>;
        }

    • react module is the core react library
    • react-dom has DOM APIs for react applications
    • As discussed in my previous article, we would need Babel, to transpile JSX expressions
    • Babel will transpile above code to plain JS or syntax that browser will understand:

    •   const Greetings = () => {
                             
          return React.createElement(
            "h1", //type of html element to create
            {},   //props required/passed from parent
            "This is Hardik, this is my first component!" //content or childerns
          );
        };


    • Because post transpile, return statement will be converted to React.createElement; hence we must include react module event though we may not be using it directly 

  • Class Components

    • Its similar to functional component except there is a default method for every class, called as render()
    • It can contain states unlike functional components
    • Every class component must extend from React.Component
    • render() returns the same JSX that function() used to
    • Any UI/view related logic needs to be added in the render method before return
    • We can perform conditional rendering, running loops, stylings etc. inside render()
    • Class can have its methods, we can call them using this.methodName syntax
    • render() is like a main method for that class based component

    •   class Greetings extends React.Component {
          render() {     
            return (
              <div>               //parent element
                <h6>Hello Hardik</h6> //child element
              </div>
            );
          }
        }

    • return can have parenthesis to cover multiline return
    • Post transpile:

    •   class Greetings extends React.Component {
          render() {
            return React.createElement(
              "div", //parent element
              null, //props required or passed from parent
              React.createElement("h6", null, '"Hello Hardik"') //element, props, children
            );
          }
        }

    • Above is a good example of nested elements
    • Every component eventually will have its own element sub-tree, its advised to use JSX for writing HTML templates

  • Types of Class Components

  • Class component can be of 2 types:
    • Pure Components
    • High Order Components (HOC)

    • Pure Components

      • As per functional programming paradigms, function is pure if:
      • Return value is only determined by its input values
      • Return value is same for same input values
      • React has PureComponent class for such components
      • It has performance improvements and render optimizations since it implements shouldComponentUpdate() lifecycle method for a shallow comparison for props and state
      • Functional components cannot leverage performance improvements with React.PureComponent as they are not classes by definition.
      • Using recompose package and using named import pure, functional components can be also made PureComponents.
      • If other components are rendered within these components, their rendering is also cached
      • Can be used for caching a component


      •   class SquareRoot extends React.PureComponent {
            constructor({ number }) { //props
              super({ number });
              this.state = {
                number: number, //initializing state from props
              };
            }

            render() {
              const label = "Square root of";

              return (
                <div>
                  <h2>
                    {label} : {this.state.number} is {Math.sqrt(this.state.number)}
                  </h2>
                </div>
              );
            }
          }

          export default SquareRoot;

          ReactDOM.render(
            <SquareRoot number="144" />, //setting prop value
            document.getElementById("container")
          );


    • Higher Order Components (HOC)

      • Technique for reusing component logic
      • Function that takes a component and returns a new one
      • A normal component transforms props into UI but a higher Order Component transforms a component into another
      • Returns a function or class
      • Useful where both components have same logic, finding common ground is important

      •   //Wrapped Component/Base component to reuse
          function Greetings({ message }) {
            return <h1>{message}</h1>;
          }

          // This function takes a component and returns another component
          function HOCCreator(WrappedComponent) {

            return class extends React.Component {
              render() {
                // This will render the wrapped component with the new data
                return <WrappedComponent message={this.props.message} />;
              }
            };
          }

          //create new component and use it wherever needed in same or different component
          const Welcome = HOCCreator(Greetings);

          <Welcome message={"Welcome!"} />; //passing props

  • Nested Components

    • Nested component means when one or more component(s) comprises of another component(s)
    • This will happen when we are referring or calling one or more component(s) from another
    • Nested components can be either functional or class components.


    •   function Greetings() {   //component 1
          return (
            <div>
              <Person />        //component 2
              <Message />      //component 3
            </div>
          );
        }

        //Implicit return because of arrow function without curly braces
        const Person = () => <h1>This is Hardik!</h1>; //component 2

        //Explicit return because of arrow function with curly braces
        const Message = () => {
          return <p> This is my message</p>; //component 3
        };


    • Greetings component is made of Person and Message components
    • Both Person and Message components will have access to props provided by Greetings if any.

  • Thumb Rules for React Components

    • The extension of the component file can be either .js or .jsx
    • Always export default class/function per file
    • During return, JSX expression must have one parent element, meaning there should be only one parent element in one render function


      •   function Greetings({ message }) {
            return (
                <h1>Hello World!</h1>       //Error
                <button>Increment</button> //Error  
            );
          }

      • Error occurs because of React.CreateElement  as it doesn’t understand type of the element it needs to create in case of multiple elements
    • Automatic semicolon insertion – in front of return, JS automatically adds semicolon and any content on next line is ignored. To solve this problem, use parenthesis and add content and close it.
    • Avoid div hell - don’t add an additional div just to cover child the element or content, hence we use React.Fragment or <>. This will add placeholder empty element until compilation and will be removed from actual DOM.
    • Use Camel-case for html element attributes, built-in functions
      • onClick, onChange
    • Component name should follow Pascal case (upper Camel-case)
    • One file can have multiple named exports but only one default export.




Comments

Popular Posts