1 the introduction

React Conditional rendering Methods

8 React conditional rendering methods are introduced.

Template conditional rendering is very common, and is often used in a random way, so how to write better maintainability? Let’s learn about the eight conditional rendering methods.

2 an overview

IF/ELSE

Since JSX supports mixing OF JS and HTML, using it interchangeably can solve the conditional rendering problem:

function render() { if (renderComponent1) { return <Component1 />; } else { return <div />; }}Copy the code

return null

If you do not want to render empty elements, it is better to use null instead of an empty div:

function render() { if (renderComponent1) { return <Component1 />; } else { return null; }}Copy the code

This improves React rendering efficiency.

The component variables

Assign a component to a variable, and you can modify it as much as you want before returning.

function render() {
  let component = null;

  if (renderComponent1) {
    component = <Component1 />;
  }

  return component;
}
Copy the code

Ternary operator

The syntax of the ternary operator is as follows:

condition ? expr_if_true : expr_if_false
Copy the code

JSX is also handy:

function render() {
  return renderComponent1 ? <Component1 /> : null;
}
Copy the code

But when ternary operators generate nesting, the cost of understanding becomes high.

&&

This is the most commonly used, because it has the least amount of code.

function render() {
  return renderComponent1 && <Component1 />;
}
Copy the code

IIFE

IIFE means to execute the function immediately.

(function myFunction(/* arguments */) {
  // ...}) (/* arguments */);
Copy the code

When you’re stuck in JSX code and want to write a chunk of logic, instead of going back to the top, you can use IIFE:

function render() {
  return (
    <div>
      {(() => {
        if (renderComponent1) {
          return <Component1 />;
        } else {
          return <div />;
        }
      })()}
    </div>
  );
}
Copy the code

Child components

This is a variant of IIFE, which replaces the immediate function with a normal function:

function render() { return ( <div> <SubRender /> </div> ); } function SubRender() { if (renderComponent1) { return <Component1 />; } else { return <div />; }}Copy the code

IF a component

Make a conditional render component IF instead of the js function IF:

<If condition={true}> <span>Hi! </span> </If>Copy the code

The component implementation is also simple

const If = props => {
  const condition = props.condition || false;
  const positive = props.then || null;
  const negative = props.else || null;

  return condition ? positive : negative;
};
Copy the code

High order component

A higher-order component is a function that returns a new component and takes a component as an argument.

We can write conditional statements in higher-order components and return different components:

function higherOrderComponent(Component) { return function EnhancedComponent(props) { if (condition) { return <AnotherComponent {... props} />; } return <Component {... props} />; }; }Copy the code

3 intensive reading

With so many approaches to conditional rendering, the key is readability and maintainability.

For example, to render a component by calling a function:

<div>{renderButton()}</div>
Copy the code

It still looks redundant, but if we use the renderButton getter definition, we can write it like this:

<div>{button}</div>
Copy the code

What we really want is a button, not a renderButton. You can go one step further and simply encapsulate JSX components:

<div>
  <Button />
</div>
Copy the code

Whether this effort is necessary depends on the complexity of the application. If your application is very complex, you should try to use the last encapsulation, keeping the logic of each file as separate and simple as possible.

If the complexity of your application is low, be careful not to over-encapsulate it so you don’t wind yourself up.

So again, this is an open-ended question, and the choice of encapsulation depends on the complexity of the application.

Application complexity

Any encapsulation of code increases the complexity of this join logic.

Given that the complexity of the code is constant no matter what, here is code with a connection complexity of 0 and a logic complexity of 100 for the render function:

function render() { if (renderComponent) { return isOk ? <Component1 /> : <Component2 />; } else { return <div />; }}Copy the code

The following code is split into two functions with logic complexity of 50 for render SubComponent, but connection complexity of 50:

function render() {
  if (renderComponent) {
    return <SubComponent>;
  } else {
    return<div />; }}function SubComponent() {
  return isOk ? <Component1 /> : <Component2 />
}
Copy the code

As you can see, we have reduced the logical complexity of each function through function splitting, but increased the join complexity.

As a comparison, let’s assume that a normal programmer can easily memorize 10 functions at once. Any more, and the call relationships between functions become confusing.

Low application

When the amount of application code is relatively small, suppose that there are 10 functions in total, if the logical abstraction is done and 10 subfunctions are split, then the total logical complexity remains the same and the functions become 20.

At this point, Xiao Wang needs to modify the project, he needs to find the location of the key code.

Without logical abstraction, Xiao Wang memorized 10 functions and completed the requirements quickly.

If the application abstracts logically, the complexity of the logic it needs to understand remains the same, but the number of functions it needs to read becomes 20. Wang needs to jump from clue to clue like a detective, he still only found 10 key functions, but there are only 20 functions in total, the logic is not complicated, is it worth it?

Xiao Wang’s heart may whisper: simple logic blind abstraction, harm my documents to find a long time!

Larger application

So we’re going to have a lot of code, and we’re going to have 500 functions, and we’re not going to take into account the reuse benefits of abstraction, and we’re going to be able to reuse all of them, and we’re going to have the same logical complexity, and we’re going to have 1,000 functions.

At this point, Xiao Wang received the demand and finally maintained a large project.

Xiao Wang knew that the project was very complicated and did not feel that he could understand the whole picture of the project from the very beginning, so he regarded himself as a detective and prepared to explore step by step.

Now there are two choices, one is to explore without doing logical abstraction, and one is to explore after doing logical abstraction.

Without logical abstraction, Wang would face 500 of these functions:

function render() { if (renderComponent) { return isOk ? <Component1 /> : <Component2 />; } else { return isReady ? <Component3 /> : <Component4 />; }}Copy the code

If you do logical abstraction, Wang needs to face 1000 of these functions:

function render() { if (renderComponent) { return <Component1And2 />; } else { return <Component3And4 />; }}Copy the code

After the project is large, the total number of functions does not affect the search for clues, and the total depth of clues is almost always fixed, generally around 5 layers.

Xiao Wang understands that the cost of 5 or 10 functions is almost the same, but without logical abstraction, these 5 functions are mixed with other logic, which affects the understanding of the function.

This is where logical abstraction is appropriate.

4 summarizes

So in general, I prefer to use sub-functions, sub-components, IF components, higher-order components to do conditional rendering, because these four ways can improve the program’s abstraction ability.

Often the abstracted code is more reusable, the logic of individual functions clearer, and easier to understand when programming in cuts.

When the project is simple, the cost of understanding the entire project is low, and the complexity of abstractions makes the project a piece of faceted programming, which is not worth the cost.

To sum up:

  • It is recommended in code when the project is simple or when the logical validation of conditional rendering cannot be reused&&Or ternary operators, IIFE and other direct implementation of conditional rendering.
  • When the project is very complex, try to use subfunctions, subcomponents, IF components, high-order components to do more abstract conditional rendering.
  • When doing logical abstractions, consider the complexity of the project to avoid the cost of abstractions and the fragmentation of a project that can be understood as a whole.

5 More Discussions

React 8 Conditional Rendering · Issue #90 · dt-fe/weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays.