Use Array.map() to Dynamically Render Elements

Use Array.map() to Dynamically Render Elements
0

#1

Tell us what’s happening:
This code works as it should but I am still failing the test. I don’t understand why.

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(function(item){
      return <li> {item} </li>;
    });
    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 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/react/use-array-map-to-dynamically-render-elements


#2
      return <li> {item} </li>;

For some reason, the spaces before and after {item} are confusing the test.


#3

Why does this line not run into JavaScript error? i mean when we are writing js directly in render() before returning then shouldn’t js rules be applied as well hence instead of writing <li>{item}</li> shouldn’t we return a string "<li>{item}</li>". i think i have overlooked some concept here.


#4

Because it’s not JS, it’s JSX. This:

<li>{item}</li>

is a combination of html and injected JS called JSX. React converts it to the necessary html and JS. It is being used in a JS environment, but it is not JS yet.

If we run this code:

class Test extends React.Component {
  render() {
    const value = 'howdy'
    const jsxElement = <p>{value}</p> 
    console.log(jsxElement)
    return (
      <div>
        {jsxElement} 
      </div>
    )
  }
}

We see this in the console:

{$$typeof: Symbol(react.element), type: “p”, key: null, ref: null, props: {…}, …}
$$typeof: Symbol(react.element)
key: null
props: {children: “howdy”}
ref: null
type: “p”
_owner: p {_currentElement: {…}, _rootNodeID: 0, _compositeType: 0, _instance: Test, _hostParent: null, …}
proto: Object

And if we inspect the DOM, we see

<div data-reactroot=""><p>howdy</p></div>

So we see that a transformation has taken place. That is what React is doing for us behind the scenes.

Try to remember that JSX is not HTML and and it is not JS. It looks like HTML with JS injected and React will do what is needed to convert it into something the browser can read.

We are used to putting JSX in the return of the render method but it can also be stored in variables, arrays, passed as parameters, etc.

Here is a pen with which you can see this.