映射对象数组将返回未定义的

时间:2020-02-13 19:33:29

标签: javascript reactjs

在React应用程序中,我试图将+1增加到数组中每个对象的id字段。

function App() {
  const[todos, setTodos] = useState([
    {
      id: 1,
      title: 'Take out the trash',
      completed: false
    },
    {
      id: 2,
      title: 'Dinner',
      completed: false
    },
    {
      id: 3,
      title: 'Meeting with boss',
      completed: false
    }
  ]);

  function onClick(){
    setTodos(todos => todos.map(todo => todo.id = todo.id + 1))
  }

  return (
    <div className="App">
      <div className="todo-list">
        <ul>
          {todos.map(todo => <li>{todo.id},{todo.title},{String(todo.completed)}</li>)}
        </ul>
        <button onClick={()=>onClick()}
        >Update
        </button>
      </div>
    </div>
  );
} 

在页面的初始渲染中,对象列表正确显示。首次单击按钮时,它们将更改为:

,,undefined
,,undefined
,,undefined

在第3次点击此错误:

TypeError: Cannot create property 'id' on number '2'

我想念地图功能吗?

4 个答案:

答案 0 :(得分:4)

function onClick(){
  setTodos(todos => todos.map(todo => todo.id = todo.id + 1))
 }

您要从地图函数返回todo.id,因此将待办事项设置为ID为[2, 3, 4]的数组。然后,当您尝试访问todo.id时,它是undefined,因为number.id是未定义的`。

您还可以通过说todo.id = ...来改变状态。如果在设置状态时发现自己使用分配操作器(=),则可能是做错了什么。您不应该拥有state = ...

您想要执行以下操作:

function onClick(){
  setTodos(prev => prev.map(t => ({ ...t, id: t.id + 1 })))
 }

在创建阴影变量名称时,我也将todos重命名为prev

答案 1 :(得分:1)

您实际上并没有在其中返回新的todo实体,而只是返回了id属性,那是一个错误。解决方法是

  function onClick(){
    setTodos(todos => todos.map(todo => ({ ...todo, id: todo.id + 1 })))
  }

:)

答案 2 :(得分:1)

Map函数迭代到每个值,并返回您在迭代器中计算出的映射值。

您的代码将待办事项对象数组转换为递增的待办事项ID数组,例如[2,3,4],因此,当您的下一个map方法运行时,它将给出您面临的错误。第一次,您的地图将对象转换为整数。

您应该更新地图方法,例如:todos.map(todo => ({...todo, id: todo.id + 1}))

注意:同样,您也不需要在setTodos挂钩中写入todos =>

答案 3 :(得分:0)

您的map函数不会返回对象,但是我认为您应该使用reduce JavaScript函数

function onClick() {
    const reducerFunction = (r, v) => r.concat({ ...v, id: v.id + 1 })
    setTodos(
      todos.reduce(reducerFunction, [])
    );
}

我还认为您应该尝试使用useReduce挂钩,这样可以使解决方案更加简洁。

useState的替代方法。接受类型的变径(状态,动作) => newState,并返回与调度方法配对的当前状态。 (如果您熟悉Redux,您已经知道 有效。)

当您遇到复杂的情况时,

useReducer通常比useState更可取 涉及多个子值或下一个状态的状态逻辑 取决于前一个。 useReducer还可以让您优化 触发深层更新的组件的性能,因为您可以 向下传递调度而不是回调。