React - Use Array.map() to Dynamically Render Elements - .map is different than in js

Tell us what’s happening:
The .map method in this challenge is some crooked JavScript…
What is this ?

this.state.toDoList.map(item => <li>{item}</li>)

normally JavaScript wouldn’t spit anything out of that… an object surrounded by strings without quotation marks…
The previous challenges stated that we use normal js in render method, before return statement. So can anybody explain to me what this line is ?

The second thing is, how jsx interpreted an array as string of letters ? There was nothing mentioned about array interpretation. We have to use

<ul>{[mapped Array]}</ul>

in this challange. How on earth does this work ? There was nothing about feeding an array to the render section, so I don’t undeerstand anything from this challange…

Can somebody explain it to me please ?

Your code so far

const textAreaStyles = {
    width: 235,
    margin: 5
  };
  
  class MyToDoList extends React.Component {
    constructor(props) {
      super(props);
      // Change code below this line
      this.state = {userInput: '', toDoList:[]}
      // Change code above this line
      this.handleSubmit = this.handleSubmit.bind(this);
      this.handleChange = this.handleChange.bind(this);
    }
    handleSubmit() {
      const itemsArray = this.state.userInput.split(',');
      this.setState({
        toDoList: itemsArray
      });
    }
    handleChange(e) {
      this.setState({
        userInput: e.target.value
      });
    }
    render() {
      const items = this.state.toDoList.map(item => <li>{item}</li>);  // WHAT IS THIS ?!
      return (
        <div>
          <textarea
            onChange={this.handleChange}
            value={this.state.userInput}
            style={textAreaStyles}
            placeholder='Separate Items With Commas'
          />
          <br />
          <button onClick={this.handleSubmit}>Create List</button>
          <h1>My "To Do" List:</h1>
          <ul>{items}</ul>
        </div>
      );
    }
  }

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0

Challenge: React - Use Array.map() to Dynamically Render Elements

Link to the challenge:

This is JSX. It’s common practice to insert variables like this.

As for the array, it works like this:
User input is a comma-separated list of items.
When submitted, this is split into an array and assigned to this.state.toDoList.
You can then map the items in this array to individual li elements, assigned to the variable items.

<li>{item1}</li>
<li>{item2}</li>
<li>{item3}</li>
...

items is then rendered within the ul element in the return statement.

According to one of the previous challenge description, this part of code is not JSX, it’s javaScript:

Use Advanced JavaScript in React Render Method
“You can also write JavaScript directly in your render methods, before the return statement, without inserting it inside of curly braces. This is because it is not yet within the JSX code”

That’s what I don’t understand here.

The second thing I still don’t fully get is this:
the code:

const items =this.state.toDoList.map(item => <li>{item}</li>)

put’s the mapped array (some weird type of array) here:

<ul>{items}</ul>

right ?
Does it mean that jsx, when given an array in curly brackets will render the contents of the array without comas ? Or does map method work differently in jsx and it feeds the content of the array one by one to {items} section ?

Ah, ok think I understand your confusion.

In React, what you’re writing is regular Javascript, unless you’re writing any JSX code.
(JSX is a syntactical extension to Javascript, which allows you write React ‘elements’, to be rendered to the DOM).

This is the important bit: Curly braces are required to escape to JavaScript, within JSX code.

You can also write JSX outside of your render method if you need to, in which case you still need to escape any Javascript code.

In this case:

  1. The user input is a comma-separated list.
  2. When submitted it is split into an array (itemsArray), removing the user-inserted commas to leave a regular array of items:
['red', 'blue', 'green', ... ]
  1. Now, in your render method, you use a regular map arrow function which happens to include some JSX. So you escape to Javascript to insert each Javascript mapped item (in this case ‘red’, ‘blue’ etc) inside a li element. This becomes the assigned value of the variable items.
<li>red</li>
<li>blue</li>
<li>green</li>
...
  1. Finally, in your return statement you create a ul and escape to Javascript to insert the items variable (which is the above series of li elements).
1 Like

1.the output of the const items (maped array) is an array, right ?
How come you get the output from above ?

  1. So is this:
const items =this.state.toDoList.map(item => <li>{item}</li>)

javaScript or JSX ? According to the statement from the lessons it shoud be javaScript, but the syntax is not javaScript for sure - especially the .map part if I’d fire it upe as normal .js script it would throw out a hundred syntax errors here:

=> <li>{item}</li>

feeding an array to the output, .map function with syntax I’ve never seen before, and no info about anything around it, its super confusing…

P.S. Thank You for trying to help.

const items = this.state.toDoList.map(item => <li>{item}</li>)

Everthing before the opening li tag is Javascript.
You are mapping item (which is each element in the array in turn), into a JSX element. The curly brackets are there to escape back into Javascript inside the JSX part of the code (which is only the li element).

Yes, even in this case the map method technically maps an array to another array, as it would ordinarily.

However, my understanding is that, when you map array items into JSX elements, you create an array of objects which - when the code is transpiled and rendered to the DOM - will be rendered as DOM elements.

So although the variable items is an array, it will be interpreted as a sequence of elements, when rendered inside the return statement.

Try console.log(items) just after the map statement to see the new array.

Ok, this is the part I don’t understand.
the .map method used on array normally returns the mapped array, right ?
How can it work in a different way if it’s still javaScript ?
Probably that’s where I got problem understanding this. I don’t understand what’s the data type of the output, and why it is not an array.

Sorry, I’m not great at explaining. I tried to reword my response above a little more clearly because I think it was a little misleading.