Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is this span tag needed?

Why is a span tag needed inside of this array mapping? (see >>)


const asciiArray = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'];
const gridWidth = 4;

const AsciiGrid = () => (
  <div style={{ backgroundColor: 'black', color: 'white', fontFamily: 'monospace' }}>
    {Array.from({ length: Math.ceil(asciiArray.length / gridWidth) }, (_, i) => i).map(i => (
      <div key={i}>
        {asciiArray.slice(i * gridWidth, i * gridWidth + gridWidth).map((char, j) => (
>>            <span key={j}>{char}</span>
        ))}
      </div>
    ))}
  </div>

);

If I remove it and just leave {char}, React gives an error of:

Objects are not valid as a React child.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If I leave just {{char}}, I get an unexpected token error.

>Solution :

In React, inside JSX, once your code is inside { braces } it becomes vanilla Javascript. When you say {char} – this is not JSX interpolating the variable char into the template. Instead, it’s vanilla Javascript shorthand for {char: char}. This is also happening because you are accidentally invoking fat arrow function return shorthand syntax.

Because {arr.map(x => ({x}))}, specifically a parenthesis followed by an open curly brace, is the fat arrow function shorthand for "return an object".

const a = (x) => ({x})

specifically ({...}) means "return an object without requiring an explicit return statement".

It’s also invoking the shorthand {x} in Javascript which means create a key named x with the value set to the contents of variable x, aka {x: x}.

Also React can’t render objects as children. <div>{{x: 1}}</div> will cause an error. Note this is the object {x: 1} inside JSX interpolation { brackets }.

You can do

{asciiArray.slice(i * gridWidth, i * gridWidth + gridWidth).map((char, j) => (
  char
))}

(note no wrapping { }) but it will probably yell at you for no key.

You can do

{asciiArray.slice(i * gridWidth, i * gridWidth + gridWidth).map((char, j) => (
  <React.Fragment key={j}>{char}</React.Fragment>
))}

if you don’t want a span tag.

As a side note: in the final code block, you can see that {char}, surrounded by curly braces, is nested inside {array.map(...)}. You can nest curly brace interpolation with JSX, but you need to re-enter JSX first. {char} works here because it’s re-wrapped inside a JSX element.

Edit: As the commenter pointed out, you can also remove the map entirely if you only want to output text, because React can automatically render arrays of primitive values.

{asciiArray.slice(i * gridWidth, i * gridWidth + gridWidth)}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading