Original is not easy, I hope you can pay attention to us, and then easily point a praise ~~

This article was first published in the front end of the cloud blog: Heaven and earth move! React can also “use” computed properties

Preface, about computing properties

The first time I saw the term computed properties was in the section “Computed properties and Listeners”, the official Vue document, which describes computed properties as follows:

Expressions in templates are very convenient, but they are designed for simple calculations. Putting too much logic into a template can make it too heavy and difficult to maintain.

Thinking back to the React code we wrote, was there too much logic in JSX that made the Render function too big to maintain?

Evaluate properties in React

React before we talk about React, let’s take a look at Vue. In Vue, calculated properties have the following two features:

  1. Computed properties create dependencies declaratively, and changes to the dependent data or props trigger recalculation and automatic updates.
  2. Computed properties are cached based on their reactive dependencies.

In React, evaluate properties are also visible. If you are familiar with React, you may have written code like the following:

import React, { Fragment, Component } from 'react';

class Example extends Component {
  state = {
    firstName: ' '.lastName: ' '}; render() {// Handle the logic in the render function
    const { firstName, lastName } = this.state;
    const fullName = `${firstName} ${lastName}`;
    return <Fragment>{fullName}</Fragment>; }}Copy the code

In the above code, fullName in the render function depends on firstName and lastName in props. The fullName variable is automatically updated when firstName or lastName is changed. This works by saying that changes in props and state cause the render function to be called, which then recalculates the derived values.

Although we can do the calculation, we put the calculation logic into the render function, which causes it to be bloated, which is not elegant. It is better to extract the calculation logic and simplify the render function logic:

class Example extends Component {
  state = {
    firstName: ' '.lastName: ' '};// Reduce render function bloat by separating the logic in render into functions
  renderFullName() {
    const { firstName, lastName } = this.state;
    return `${firstName} ${lastName}`;
  }

  render() {
    const fullName = this.renderFullName();
    return <Fragment>{fullName}</Fragment>; }}Copy the code

If you know anything about Vue, you know that its underlying, computed properties use getters, just getters for objects. React also uses the getter of a class to evaluate properties:

class Example extends Component {
  state = {
    firstName: ' '.lastName: ' '};// Use getters instead of function forms to reduce variables
  get fullName() {
    const { firstName, lastName } = this.state;
    return `${firstName} ${lastName}`;
  }

  render() {
    return <Fragment>{this.fullName}</Fragment>; }}Copy the code

Further, memoization is used to optimize the calculated attributes

As mentioned above, when calculating attributes in Vue, compared to function execution, there will be caching and less computation. Because a calculated property is reevaluated only when its associated dependencies change.

This means that as long as firstName and lastName have not changed, multiple visits to the fullName computed attribute will immediately return the previous computed result without having to execute the function again.

React getters also have cache advantages. The answer is: no. The React getter is not cache optimized!

Not to be disappointed though, we can use Memoization to optimize our computational properties to the same effect as the computational properties in Vue. We need to introduce the Memoize-One library into the project as follows:

import memoize from 'memoize-one';
import React, { Fragment, Component } from 'react';

class Example extends Component {
  state = {
    firstName: ' '.lastName: ' '};// If it is the same as the last parameter, 'memoize-one' will repeat the last value.
  getFullName = memoize((firstName, lastName) = > `${firstName} ${lastName}`);

  get fullName() {
    return this.getFullName(this.state.firstName, this.state.lastName);
  }

  render() {
    return <Fragment>{this.fullName}</Fragment>; }}Copy the code

Further, use React Hooks to optimize the calculated properties

The memoiz-One library used in React above achieves a similar effect to computed properties (computed) in Vue, based on dependency caching. React 16.8 has a new Hooks feature that provides a more elegant encapsulation of logic. For those of you who don’t already know Hooks, read our article on how to play with Them as well.

Here, we need to use useMemo. The official introduction to useMemo is here. React calls the callback function when the values in the dependency list change and caches the result returned by the callback function:

import React, { useState, useMemo } from 'react';

function Example(props) {
  const [firstName, setFirstName] = useState(' ');
  const [lastName, setLastName] = useState(' ');
  // Use the useMemo function to cache the calculation
  const renderFullName = useMemo((a)= > `${firstName} ${lastName}`, [
    firstName,
    lastName,
  ]);

  return <div>{renderFullName}</div>;
}
Copy the code

conclusion

This article shows how React performs a computation-like effect in Vue (computed properties), which decouples logical computations from view renderers and reduces the complexity of the render function based on dependent cache computations.

From a business development perspective, Vue provides apis that greatly improve development efficiency. React doesn’t have official native API support in some cases, but thanks to a vibrant community, there are always solutions to problems you encounter. And while exploring these solutions, we can also learn a lot of classical programming ideas to help us more reasonable use of the framework, with technology to solve business problems.

, recruiting

ZooTeam, more than 50 partners are waiting for you to join the wave ~ If you want to change things have been torturing, I hope to start torturing things; If you want to change, you’ve been told you need more ideas, but you don’t have a solution. If you want change, you have the power to make it happen, but you don’t need it. If you want to change what you want to accomplish, you need a team to support you, but you don’t have the position to lead people. If you want to change “5 years of work and 3 years of experience”; If you want to change the original savvy is good, but there is always a layer of fuzzy window… If you believe in the power of believing, believing that ordinary people can achieve extraordinary things, believing that you can meet a better version of yourself. If you want to be a part of the growth of a front end team that has deep business understanding, technology systems, value creation, and impact spillover as the business takes off, I think we should talk. Any time, waiting for you to write something and send it to [email protected]

Recommended reading

Visual Construction System for Front-end Engineering Practice (PART 1)

Serverless Primer for front-end engineers

Automated Web performance optimization analysis solution