Michael Curran
['Hip', 'Hip'] - A Web Dev Blog

Follow

['Hip', 'Hip'] - A Web Dev Blog

Follow
You're "React"ing Wrong

You're "React"ing Wrong

Incorrect uses of React you should know about.

Michael Curran's photo
Michael Curran
Β·Jun 6, 2022Β·

3 min read

Table of contents

  • You Might Be "React"ing Wrong Let's Check Out Why.

photo.jpeg

You Might Be "React"ing Wrong Let's Check Out Why.


Intro

In this post series we are going to explore some common React mistakes I have come across or made myself in React codebases. Every week we will quickly explore things that can trip you up or produce unintended results in our code. We will also mostly be focussing on React codebases. Hence the series title, You're "React"ing Wrong. First installment of the series, let's jump to it!

image.jpg

Using "&&" with array.length can give unexpected results

Working in React codebases you might often see the && operator to conditionally display a component or content.
You can occasionally find it used like so...

const App = () => {
  const [ list, setList ] = useState([])

  // Simulate getting some data
  setTimeout(() => {
    setList([ 'something', 'something else' ])
  }, 2_500)

  return (
    <div className="app">{ list.length && <List list={list}/> }</div>
  )
}

So What? What happens?

All we are trying to do in this code is simulate fetching some data in a 2.5 second timeout function. Then in a component we call <List />, we map out that array displaying each element in a <div> element. Then we use the && operator to conditionally display that list component!
Now, run the code below or check out the sandbox and see what happens. I think you may be surprised by the result!

const List = ({ list = [] }) => {
  return (
    <div>
      {
        list.map((item) => {
          return <div>{ item }</div>
        })
      }
    </div>
  )
}

const App = () => {
  const [ list, setList ] = useState([])

  // Simulate getting some data
  setTimeout(() => {
    setList([ 'something', 'something else' ])
  }, 2_500)

  return (
    <div className="app">{ list.length && <List list={list}/> }</div>
  )
}

Running this code you can see, "0" will be momentarily rendered before the list is populated. Obviously not the goal of the written code and not great for a production application.

Why does it happen?

From MDN docs : β€œThe logical AND (&&) operator (logical conjunction) for a set of boolean operands will be true if and only if all the operands are true. Otherwise, it will be false.”

What this means is, && returns the value of the first falsy operand that is found when evaluating from left to right, or the value of the last operand if all are truthy.

The empty initial array in our code evaluates as falsy and the length of the array is returned because React does not ignore falsy values on render. Then when our data eventually fetches we return the intended component.

How to solve it

A few ways we can solve this issue below....

// 1. Use a ternary expression with null
list.length ? <List list={ list }/> : null

// 2. Control with specific logic
list.length >= 1 && <List list={ list }/>

// 3. Convert list.length to boolean
!!list.length && <List list={ list }/>

What's Next!

Thanks for reading! The plan is to make this a weekly installment where we look at some common mistakes in React, why they happen, what happens, and how to avoid the mistake. So if you enjoyed this post or learned something, make sure to check back by next week when we tackle another common mistake. Or better yet, give the blog a subscribe!

Til next time! πŸ™‚

Did you find this article valuable?

Support Michael Curran by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
Β 
Share this