首页 > 解决方案 > how to call a React function in a loop without an event?

问题描述

React code: I'm trying to use a simple counter in a loop to count each of my todo list items, but I can't seem to execute the code in React. I simply need countopen and countcomplete to get populated and then display them on screen.

countopen and countcomplete are both set in the state, I thought that would be easiest...

App.js ...


    //I tried putting my code out in a separate block, then calling it but that doesn't work
    todos.map((todo, index) => {
    if (todo[index].completed === 0) {
        setCountopen(countopen + 1);
    } else {
        setCountcomplete(countcomplete + 1);
    }})
  }
    <div className="App">
        <div className="todo-list">
            {todos.map((todo, index) => (
              <Todo key={index} index={index} todo={todo} completeTodo={completeTodo} tallyTodos={tallyTodos} />

    //i tried putting my code here, no dice React throws syntax errors

        **if (todo[index].completed === 0) {
            setCountopen(countopen + 1);
        } else {
            setCountcomplete(countcomplete + 1);
        ))}**

            Open: {countopen} Closed: {countcomplete}
      </div>
    </div>
  );

So I suppose the question to answer is: How do I code my if/else code to get looped over in React? I thought I could piggy back my .map function but nope. I simply need to tally the 2 types of todos and display them in {countopen} and {countcomplete}

Thanks in advance!

标签: reactjsfunctionloops

解决方案


This is a derived state and it is best to avoid replicating that in the state as this is prone to desynchronization with the source state value. You should compute it on the fly in the render or if the computation is expensive, use a caching strategy like useMemo React hook.

Before the return you can compute the values using a for loop or compute the length of the filtered todo list that includes only the completed items.

The countopen is always just the difference between todos count and number of completed items - a simple const is enough.

Please see the example below:

let countcomplete = 0;

for (const todo of todos) {
  if (todo.completed !== 0) {
    countcomplete++;
  }
}

// --or--

const completedTodos = todos.filter(todo => todo.completed !== 0);
countcomplete = completedTodos.length;

const countopen = todos.length - countcomplete;

return (
  <div className="App">
    <div className="todo-list">
      {todos.map((todo, index) => (
        <Todo key={index} index={index} todo={todo} completeTodo={completeTodo} tallyTodos={tallyTodos} />
      )}
      Open: {countopen} Closed: {countcomplete}
    </div>
  </div>
);

推荐阅读