Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

The Functional Side of React

DZone's Guide to

The Functional Side of React

If you're a web developer, odds are you'll need to know a little bit about React. Read on to learn how to write functional-oriented JS code with React.js.

· Web Dev Zone ·
Free Resource

Bugsnag monitors application stability, so you can make data-driven decisions on whether you should be building new features, or fixing bugs. Learn more.

Imagehttps://pixabay.com/it/ingranaggio-ingranaggi-funzione-240137/ title

As you know, React is one of the most popular JavaScript libraries to create web-based user interfaces. Its success is due to several factors, but maybe one of them is its clean and effective approach to programming.

In the React environment, every piece of a UI is a component. Components can be composed together to create other components. The application itself is a component: a composition of components. The developer approaching React is naturally led to think of it in terms of Object-Oriented Programming. The syntax itself to define a component promotes this idea:

class HelloReact extends Component {
  render() {
    return (<div>Hello React!</div>);
  }
}

However, under the Object-Oriented dress, React hides a functional nature. Let’s find out how.

Rendering an Output

The main constraint for a React component is to implement a render() method. A component without a render() method is not a React component. The render() method returns a React element, that is the component’s markup defining its appearance. In other words, React is requiring that any component must have an output. This could make you think of a component more in terms of a function than of an object: a component is something that returns an output based on an input.

Components as Functions

Actually, not only you can think of React components as functions. You can implement them as functions. The following code shows how to implement with a function the component we defined above:

const HelloReact = () => <div>Hello React!</div>;

As you can see, it is a simple and compact way to implement the component.

In addition, you can pass arguments to the function, as in the following example:

const Hello = (props) => <div>Hello {props.name}!</div>;

You passed the props argument, that is just the props object used to pass data from one component to another.

Immutability of Props

As you know, props are immutable, you can read them but you cannot change them. This is one of the aspects that moves React components towards a truly functional approach. Since props are the input argument of a component, granting their immutability avoids side effects. In fact, this is a fundamental rule in functional programming: no input argument must be changed by a function. This is one of the basic principles to create pure functions.

Unidirectional Data Flow

Another feature of the React environment is unidirectional data flow. This means that in a component’s hierarchy, data must flow from the higher up component towards the lower component, not vice-versa. This concept may require a little effort if we think of components as objects. Instead, it should be quite natural if we think of the components in terms of functions. Unidirectional data flow is just the effect of function composition.

Consider the following code:

class App extends Component {
  render() {
    return (<Hello name="John" />)
  };
}

class Hello extends Component {
  render() {
    return (<div>Hello {props.name}!</div>);
 }
}

It describes two components: the App component using the Hello component to show the Hello React! text. It also defines an implicit hierarchy between the App and the Hello components. However, at a first sight, it is not so clear the unidirectional flow of the name property’s value.

Now, consider the following version of the same code:

const App = () => <Hello name="John" />;
const Hello = (props) => <div>Hello {props.name}!</div>;

It should appear clear that the component hierarchy is nothing but the composition of the function App() and the function Hello(). You could think of it as the following:

const App = () => Hello("John");

The passage of the value from App to React and not vice versa should be more evident.

Composition vs Inheritance

In the object-oriented programming paradigm, it is natural to think of inheritance as a mechanism to specialize a class. However, if you think of React components in terms of functions, this approach is not so natural.

For example, suppose you want to specialize your Hello component so that it also shows a welcome message. You can simply create the new component by composing it with the Hello component, as in the following example:

const HelloAndWelcome = (props) => <div><Hello {…props} /><p>Welcome to React!</p></div>;

As declared by the Facebook team, you'll rarely need inheritance.

Higher-Order Components and Higher-Order Functions

A higher-order component is a common pattern in React programming. It allows for the reuse of component logic to create a new component. In simple terms, a higher-order component is a function that takes a component as input and returns a new component as its output. The following is an example of a higher-order component:

const AddWelcome = (GreetingComponent) => {
  class TheNewComponent extends Component {
    render() {
      return (
        <div>
          <GreetingComponent {…this.props}/>
          <p>Welcome to React!</p>
        </div>);
      }
    }

  return TheNewComponent;
};

The function AddWelcome() takes the GreetingComponent argument and uses it in the render() method of a new component definition, TheNewComponent. This new component simply adds a welcome message after the output of the GreetingComponent. Finally, it returns the new component.

You can use this function as in the following example:

const HelloAndWelcome = AddWelcome(Hello);

You get a new component by applying  AddWelcome() to the Hello component.

You can translate the previously seen implementation of the  AddWelcome() function into a function-based approach as follows:

const AddWelcome = (GreetingComponent) => {
  const TheNewComponent = (props) => <div><GreetingComponent {…props}/><p>Welcome to React!</p></div>;

  return TheNewComponent;
};

As you can see, this is not but a higher-order function, that is a function taking another function as input and returning a new function as output.

Components and the State

The state of an application is the set of data that changes over time. The functional programming paradigm aims to avoid the use of the state in an application. In fact, the application state management is one of the main sources of complexity in software development. However, since you cannot do without it, you should at least try to limit its use and to make it more manageable.

React’s development guidelines promote the creation of stateless components, that is components not using the state property. This should grant that the output of a component only depends on its props. A stateless component looks a lot like a pure function, and indeed it is.

However, you know you cannot write a meaningful application without using the state. The trick is to isolate the state in a few points of the application, (it's even better if it's only in one point). This strategy corresponds to the pattern that asks the developer to use the state in the higher component in a component hierarchy. In other words, a component hierarchy should have in its root a stateful component, while its descendants should be stateless components. This way, we can better control the state since it is managed by a single component in the hierarchy.

Conclusions

Unlike what might seem at first glance to developers approaching React for the first time, this library promotes more functional-oriented than object-oriented tenets. In general, this allows for the writing of more formally verifiable code, for example with automatic tests, and more reliable applications. I suggest making the most of the functional features of React to write more maintainable code.

Andrea Chiarelli is the author of Beginning React.

Monitor application stability with Bugsnag to decide if your engineering team should be building new features on your roadmap or fixing bugs to stabilize your application.Try it free.

Topics:
functional programming ,object oriented programming ,web dev ,tutorial ,react.js

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}