DEV Community

Cover image for Beginner React Mistakes
Rachel Smith
Rachel Smith

Posted on • Updated on

Beginner React Mistakes

Are you starting out in React? Just as you were getting the hang of JavaScript, here comes React and JSX with little "ghosts" that sneak up on you. As a level one player, let's explore a few basic gotchas as we begin to navigate the maze of React.

Header picture with floating Pac-man ghosts and react logos, reads "React Gotchas" There are gotchas in every programming language and let's face it, even the well-seasoned players still get caught by the ghosts occasionally. You'll never get that hour of your life back that you spent searching for that error that turned out to be a minor gotcha. Don't be hard on yourself.. we have all been there.. and odds are, it will happen again.

Divider Banner with Pac-man ghosts looking at "Avoid Using Index Key Props"Keys must be unique or you will receive an error!
"Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity" React

Below when using .map() I used key={ghost.index} which triggers a warning message:

function GhostList({ ghosts }) {

  const displayGhosts = ghosts.map((ghost) => 
    <Ghost key={ghost.index} ghost={ghost} />)

  return (
      <div>
        <h1>Gotcha Ghosts</h1>
        <ul>
          {displayGhosts}
        </ul>
      </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

!Warning: Each child in a list should have a unique "key" prop., picture of console warning message You should not be using an array index for keys and should only be used as a last resort. Doing so can cause errors/bugs in your code and cause issues with component state. Level Up - Tell Me Why Instead opt for the element.id or another unique string that will identify the list item. Here I used the ghost.id for my key but alternatively I could use key={ghost.name} if there is no id available and each name is unique.

const displayGhosts = ghosts.map((ghost) => 
    <Ghost key={ghost.id} ghost={ghost}/>)

Enter fullscreen mode Exit fullscreen mode

Recently I received this warning when working with keys:
Warning: Encountered two children with the same key,  raw `1` endraw . Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version. I thought what am I doing wrong? I was dealing with an array of objects (like my ghosts), and the key's value was an array...

const ghosts = [
        {
            "id": 1,
            "name": "Inky",
            "color": "blue",
            "altNames":["Fickle", "Bashful"]
        },
        {
            "id": 2,
            "name": "Blinky",
            "color": "red",
            "altNames":["Chaser", "Shadow"]
        },
        {
            "id": 3,
            "name": "Pinky",
            "color": "pink",
            "altNames":["Ambusher", "Speedy"]
        },
        {
            "id": 4,
            "name": "Clyde",
            "color": "orange",
            "altNames":["Stupid", "Pokey"]
        }
    ] 
Enter fullscreen mode Exit fullscreen mode

When you .map() through the "altNames" array to display them on the DOM, you can not use key={ghost.id} or key={ghost.name}. These will not provide a unique key for each element of the "altNames" array (list) and you will receive an error like the one above. The following was my solution, by assigning altName as the key to each element. This only works because in this data each altName (elements in array) is unique:

function Ghost({ ghost }) {
  const displayAltNames = ghost.altNames.map((altName) => 
    <li key={altName}>{altName}</li>
  )

  return (
      <div>
        <h3>Ghost: {ghost.name}</h3>
        <p>Color: {ghost.color}</p>
        <p>Other Names:</p>
        <ul>{displayAltNames}</ul>
      </div>
  )
}
Enter fullscreen mode Exit fullscreen mode


Divider Banner with Pac-man ghosts looking at "Use React.Fragment" In JSX you can only return one parent element. Notice in the code below there are two parent <div>s with children trying to be returned. In the console, you will receive a syntax error.

function Ghost({ ghost }) {
  const displayAltNames = ghost.altNames.map((altName) => (
    <li key={altName}>{altName}</li>
    ));

  return (
      <div>
        <h2>Say hello to {ghost.name}!</h2>
      </div>
      <div>
        <h3>Ghost: {ghost.name}</h3>
        <p>Color: {ghost.color}</p>
        <p>Other Names:</p>
        <ul>{displayAltNames}</ul>
      </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

SyntaxError: /src/GhostList.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? As you can see, the error even suggests what to do. After getting this error once, you’ll know exactly what mistake to look for in your code. I wish all errors were this obvious! Now, how do you fix this? You could wrap it all in another <div> OR use <React.Fragment>. If you need those two <div>s you can now return them by wrapping your return with <React.Fragment>:

return (
    <React.Fragment>
      <div>
        <h2>Say hello to {ghost.name}!</h2>
      </div>
      <div>
        <h3>Ghost: {ghost.name}</h3>
        <p>Color: {ghost.color}</p>
        <p>Other Names:</p>
        <ul>{displayAltNames}</ul>
      </div>
    </React.Fragment>
  );
}
Enter fullscreen mode Exit fullscreen mode

Or if I just had one <div, I could replace it with <React.Fragment> or the shortened syntax <> </>

return (
    <>
      <h3>Ghost: {ghost.name}</h3>
      <p>Color: {ghost.color}</p>
      <p>Other Names:</p>
      <ul>{displayAltNames}</ul>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

You can also use <React.Fragment> to replace a wrapping element to avoid cluttering the DOM with unneeded nodes. When selecting your wrapping element, keep in mind a key is the only attribute that can be passed to <React.Fragment>. Why must JSX expressions have only ONE parent element?

Divider photo with Pac-man ghosts looking at "Capitalize Component Names" Another potential JSX snag is components must begin with an uppercase, which is quite conflicting from what we have learned in JavaScript. This new naming convention is one of the first gotchas you encounter in React. Below are two different errors triggered by forgetting to capitalize component names.

<ghost /> should be <Ghost />
console error...

Warning: The tag <ghost> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

function ghostList({ ghosts }) {...
export default ghostList;
console error....

ReferenceError: GhostList is not defined

Also check your import component names because that error will tell you something is really wrong! It is good practice to intentionally experiment with errors throughout your code when learning so you can be familiar with different error messages.

"When an element type starts with a lowercase letter, it refers to a built-in component like <div> or <span> and results in a string 'div' or 'span' passed to React.createElement." React

Footer with Pac-Man ghosts and power pellets with React logo in the center

When gathering data for the pac-man ghosts, I noticed all of them have playful names.. but then there is Clyde. When I saw the original Japanese names... poor Clyde's original name is "Stupid". There has to be some long lost story on how Clyde got his name... if you know.. share! Now it's time to chomp on another React power pellet and level up to gotchas dealing with state and hooks.

You can connect with me on LinkedIn & GitHub

Resources: Namco, React, Canva

footer picture with "Game Over" logo on it

Discussion (1)

Collapse
andrewbaisden profile image
Andrew Baisden

That's a fun way to look at it 😄