1

What is this concept called and how do I read it?

        {!auth.loading && user === auth.user._id && (
          <button type="button" className="btn btn-danger">
            <i className="fas fa-times"></i>
          </button>
        )}

My guess, is "if auth is not loading, and user equals auth.user then show the button", but why? What does the double ampersand mean?

mastercool
  • 463
  • 12
  • 35
  • It means `and`. Some REPL experimentation would explain this immediately, e.g., `"truthy" && "more truthy" && "wat"`. It's a short-hand notation, convenient for simple expressions in JSX. (Although I'd personally extract out the first two parts of the expression.) – Dave Newton Jun 16 '20 at 15:21
  • [It is well explained there](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND) – Józef Podlecki Jun 16 '20 at 15:21
  • That link is just basic operators. I know booleans, I just have not ever seen it written out like this where something after the && gets executed or returned – mastercool Jun 16 '20 at 15:26
  • @mastercool That's what *always* happens with logical expressions; the result is the last thing evaluated that satisfies the condition, as explained on MDN or the REPL example in my first comment. – Dave Newton Jun 16 '20 at 17:04

2 Answers2

1

In case of AND operator, expression is evaluated until one of the condition evaluates to false because the result will always be false, independent of the further conditions.

the expression will be evaluated from left to right and will short-circuit, i.e. evaluation of the expression will stop, as soon as any of the sub-expression evaluates to false.

JSX will be rendered if:

  1. auth.loading is false

AND

  1. user === auth.user._id is true

You could understand the conditional rendering as:

(first expression) && (second expression) && JSX

if first expression evaluates to false, no further evaluation will be done because one of the operand of && operator has already evaluated to false.

Similarly, if first expression evaluates to true but second expression is false, no JSX will be rendered.

If first expression evaluates to true and second expression also evaluates to true, then true && true && JSX will evaluate to JSX

You can look at the conditional rendering section of React docs for details.

Yousaf
  • 27,861
  • 6
  • 44
  • 69
0

The double ampersand(&&) means the logical AND operator.

The code you've provided uses short-circuit evaluation to determine whether to render the button or not. To simplify the code if auth.loading is false and user === auth.user._id is true then the button will be rendered.

More details on short-circuit evaluation with logical AND operator

expression 1 && expression 2

In the case above if expression 1 is falsy expression 2 will not be evaluated, because whether the expression 2 evaluates to true of false the result of the combined expression will be false because both the expression needs to be true for the combined expression to evaluate to true.

Example,

const funcOne = () => { console.log('called funcOne'); return false; }
const funcTwo = () => { console.log('called funcTwo'); return true; }

console.log( funcOne() && funcTwo() );

// in the case above funcTwo will not be called because 
// the firstpart of the expression funcOne() && funcTwo()
// evaluates to false (the return value of funcOne is false)

The usage of short-circuit evaluation with React

Keep in mind JSX is just syntactic sugar for function call, <button>Hello</button> will be converted to a React.createElement function call behinds the scene. That is why it is nothing different to render JSX with short-circuit evaluation than using short-circuit evaluation with regular function calls.

expr1 && expr2 && <button>Hello</button>

// will be converted to
expr1 && expr2 && React.createElement("button", null, "Hello");

// so if expr1 or expr2 evaluate to false React.createElement will not be -
// called, both expr1 and expr2 have to evaluate to true for the- 
// React.createElement function to be called
subashMahapatra
  • 6,339
  • 1
  • 20
  • 26