Having problem with Array.map() in React when I try to print all array items in unordered list

71 views Asked by At

Here is the code :

let count = 0;

function GenerateValue(tasks) {
    count += 1;
    let someValue = Math.random() * 10;
    tasks.push({key : count, value : someValue});
    console.log(tasks);
}

function RenderTasks() {
    const tasks = [];
    return (
        <>
            <button onClick={() => GenerateValue(tasks)}>Add New Item</button>
            <h1>List</h1>
            <ul>
                {<li key = {count}>{tasks.map((msg) => msg.value)}</li>}
                {/*tasks.map((msg) => <li key = {count}>{msg.value}</li>)*/}
            </ul>
        </>
    );
}
export default RenderTasks;

And here's the output :

Output

Now some explanation for my code : This is just a testing program that I made when learning React. The code is simply generating a random number and adding it to an array named 'tasks'. Now I want to print all items of 'tasks' on screen in list form. And as you can see in the output, the items are being generated and added as well in the array (you can see that in console). But I'm unable to print them on screen. Now, I think there is something very simple and easy error that I'm missing but I'm tired of checking it over and over again, and would like your help. So please help me figure out what the problem is.

Also note that there is another line of code right below the one where I try to print the list items that I have commented. I have tried that too and it is not working either. Below is the output when I try that method :

enter image description here

I will wait for our kind-hearted community's response.

As for what I triedm it is already shown in the code. And since I was learning from w3schools, you can see that my commented line is exactly like their's in their React tutorial, but the funny thing is that it is working in their program but not in mine.

This is the line I'm talking about that is in my code : {tasks.map((msg) => <li key = {count}>{msg.value}</li>)}

And this is the w3schools version for their own program : {cars.map((car) => <Car key={car.id} brand={car.brand} />)}

You can also check their program here : Check the 'Keys' section.

1

There are 1 answers

6
amandarose On BEST ANSWER

I re-organized your code a bit to work as a functional component. As others were commenting, you need to use state to re-render your components on updates. I removed count since .map allows for indexing.( you can add it back as a variable inside TaskFunction if you deem necessary )

W3 School's example works because they are not updating state. They have a list that is pre-set with values and render those values.

Lastly, your map function need to 'return' the element. As in the w3 school's example, map returns the Car component. So what you had was a little mixed up.

Hope this helps.

function App() {
  const [tasks, setTasks] = React.useState([])
  const generateValue=()=>{
    let someValue = Math.random() *10
    let newValue = {value: someValue}
    setTasks([...tasks, newValue])
  }
  return (
    <div>
      <button onClick={()=>{generateValue()}}>Add New Item</button>
      <h1>List</h1>
      <ul>
        {tasks.map((task, index)=>(<li key={index}>{task.value}</li>))}
      </ul>
    </div>
  )
}

ReactDOM.createRoot(document.querySelector("#app")).render(<App />)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>

In a comment you ask to see the state example using the old style class components -

class App extends React.Component {
  state = {
    tasks: []
  }
  generateValue = () => {
    let someValue = Math.random() *10
    let newValue = {value: someValue}  
    this.setState({ tasks: [ ...this.state.tasks, newValue ] })
  }
  render() {
    return (
      <div>
        <button onClick={this.generateValue}>Add New Item</button>
        <h1>List</h1>
        <ul>
          {this.state.tasks.map((task, index)=>(<li key={index}>{task.value}</li>))}
        </ul>
      </div>
    )
  }
}

ReactDOM.createRoot(document.querySelector("#app")).render(<App />)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>

Without public class fields -

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      tasks: []
    }
  }
  generateValue() {
    let someValue = Math.random() *10
    let newValue = {value: someValue}  
    this.setState({ tasks: [ ...this.state.tasks, newValue ] })
  }
  render() {
    return (
      <div>
        <button onClick={this.generateValue.bind(this)}>Add New Item</button>
        <h1>List</h1>
        <ul>
          {this.state.tasks.map((task, index)=>(<li key={index}>{task.value}</li>))}
        </ul>
      </div>
    )
  }
}

ReactDOM.createRoot(document.querySelector("#app")).render(<App />)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>