0

I'm a little rusty here and note sure what is going on. Here is my file:

import React from 'react';
import './Navbar.css';
import {CONTENT_LINKS_PRESENTABLE, CONTENT_LINKS_SLUG} from '../../globals'
import {Link} from "react-router-dom";

function Navbar() {
  let jsx = (<div className="navbar">
      <div className="navbar-item">
        <Link to="/" id="navbar-brand">Daniel Pahor</Link>
      </div>
      <div id="navbar-items">
      
        {for (let content in CONTENT_LINKS_PRESENTABLE) {
          <div className="navbar-item">
            <Link to={CONTENT_LINKS_SLUG[content]} className="navbar-link">{CONTENT_LINKS_PRESENTABLE[content]}</Link>
          </div>
        }}
      
      </div>
    </div>)
    
  return jsx;
}

export default Navbar;

I am getting the following error:

Parsing error: unexpected token

On line 13 (i.e. when the for loop begins)

Considering that I have embedded the JS code in the {} tags I'm not sure why this is failing

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Daniel
  • 83
  • 6
  • 1
    why not just map over the array? `{CONTENT_LINKS_PRESENTABLE.map( (link) =>
    ...
    )` alternatively you can do this for loop before you define `jsx` and push items into an array that you then use to render the navbar items
    – John Ruddell Jun 30 '20 at 20:30
  • 1
    Or if `CONTENT_LINKS_PRESENTABLE` is an object, you can do `Object.keys(CONTENT_LINKS_PRESENTABLE).map( link =>
    ...
    )` to transform the object keys into a mappable array
    – Seth Lutske Jun 30 '20 at 20:31
  • 1
    Does this answer your question? [Loop inside React JSX](https://stackoverflow.com/questions/22876978/loop-inside-react-jsx) – Emile Bergeron Jun 30 '20 at 20:31
  • @SethLutske i doubt its an object since the way `content` is used is as a lookup key `{CONTENT_LINKS_PRESENTABLE[content]}`. I believe its an array of strings :) – John Ruddell Jun 30 '20 at 20:33
  • If it's an object, there's also a good question already: [How to loop an object in React?](https://stackoverflow.com/q/39965579/1218980) – Emile Bergeron Jun 30 '20 at 20:33
  • @JohnRuddell I thought maybe it was an object because why else would you use a `for var in` loop...But like you said...who knows – Seth Lutske Jun 30 '20 at 20:35
  • Ah okay, the map() idea is pretty lit, I like it a lot, I'll try that – Daniel Jun 30 '20 at 20:37

3 Answers3

2

Replace for with CONTENT_LINKS_PRESENTABLE.map(/* ... */) so it will return array of nodes. Don't forget for keys though!

{
CONTENT_LINKS_PRESENTABLE.map(content => (
          <div className="navbar-item" key={content}>
            <Link to={CONTENT_LINKS_SLUG[content]} className="navbar-link">
              {CONTENT_LINKS_PRESENTABLE[content]}
            </Link>
          </div>
        ))
}
Amadare42
  • 415
  • 3
  • 14
2

You are only able to pass in expressions. if and for are not expressions and so cannot be used. See the react docs here. How you can get around this.

import React from 'react';
import './Navbar.css';
import {CONTENT_LINKS_PRESENTABLE, CONTENT_LINKS_SLUG} from '../../globals'
import {Link} from "react-router-dom";

function Navbar() {
  return (
    <div className="navbar">
      <div className="navbar-item">
        <Link to="/" id="navbar-brand">Daniel Pahor</Link>
      </div>
      <div id="navbar-items">
        {CONTENT_LINK_PRESENTABLE.map(content => (
           <div className="navbar-item" key={content}>
            <Link to={CONTENT_LINKS_SLUG[content]} className="navbar-link">{CONTENT_LINKS_PRESENTABLE[content]}</Link>
          </div> 
        ))}
      </div>
    </div>
  )
}

export default Navbar;

Don't forget you need to pass in a key whenever you generate list items as this is what helps react identify whether or not items have changed as specified by the docs here

John Ruddell
  • 25,283
  • 6
  • 57
  • 86
Omar Nasr
  • 406
  • 2
  • 7
1

The reason for the syntax error is that a for loop is not a JavaScript expression, per official React docs "JSX in Depth" section "JavaScript Expressions as Children":

You can pass any JavaScript expression as children, by enclosing it within {}.

Also from the section "JavaScript Expressions as Props":

if statements and for loops are not expressions in JavaScript, so they can’t be used in JSX directly. Instead, you can put these in the surrounding code.

As suggested by the other answers, a good alternative is to use map.

Will
  • 6,601
  • 3
  • 31
  • 42