数组映射函数不返回更新的项



我面临一个奇怪的问题(至少对我来说(,JS数组方法map()没有根据映射回调logi返回更新的数组。我有以下功能

1  handleChange (id){
2     this.setState((prevState)=>{
3      const todos = prevState.myTodos.map(item => {
4        if(item.id === id){
5          //console.log("ITEM.id is ",item.id,"id passed is ",id,"status is ",item.completed)
6          item.completed = !item.completed
7        }
8        //console.log("ITEM.id is ",item.id,"id passed was ",id,"new status is ",item.completed)
9        return item
10      })
11      return {myTodos : todos}
12    })
13  }

在这个功能中,我正在更新应用程序对象的状态。就在第8行的返回项之前,我可以记录输出,并看到item.commpleted发生了更改,但当回调返回项对象时,它不会将更新的项存储在todos变量中。

任何暗示都会有很大帮助。感谢期待

以下是完整的代码:App.js组件

import React from 'react';
//Importing components
import Todo from './components/Todo';
import './App.css';
//import todosData from './todosData';
const todosData=[  {
id:1,
text:"Take out the trash",
completed:true,
imageUrl : "https://environmentamerica.org/sites/environment/files/w-takeout-trash-wk1003mike-shutterstock_422191876.jpg"
},
{
id:2,
text:"Grocery Shopping",
completed:false,
imageUrl : "https://upload.wikimedia.org/wikipedia/commons/thumb/1/13/Supermarkt.jpg/240px-Supermarkt.jpg"
},
{
id:3,
text:"Clean gecko tank",
completed:false,
imageUrl : "https://i.ytimg.com/vi/hy7eLGcCU9Q/hqdefault.jpg"
},
{
id:4,
text:"Mow Lawn",
completed:true,
imageUrl : "https://cdn.theatlantic.com/thumbor/hbIVuzfmIWAZZ_zKMj1CKSeMkAM=/507x56:2754x1320/720x405/media/img/mt/2016/07/RTR20MER/original.jpg"
}
];
class App extends React.Component {
constructor(){
super()
this.state={
myTodos : todosData,
counter : 1
}
this.handleClick = this.handleClick.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleClick (){
this.setState((prevState)=>{
const counterUpdated = prevState.counter +1
return {counter : counterUpdated}

})
}
handleChange (id){
this.setState((prevState,anything)=>{
const todos = prevState.myTodos.map(item => {
if(item.id === id){
console.log("ITEM.id is ",item.id,"id passed is ",id,"status is ",item.completed)
item.completed = !item.completed
}
console.log("ITEM.id is ",item.id,"id passed was ",id,"new status is ",item.completed)
return item
})
return {myTodos : todos}
})
}
render(){
const todoItems = this.state.myTodos.map(item=> {return <Todo key={item.id} todo={item} handleChange={this.handleChange} />})
return (
<div className="App">
<header className="App-header">
React Course from vSchool. <button onClick={this.handleClick} >Counter {this.state.counter}</button>
</header>
<main className="todo-container">
<div className="todo-list">
{todoItems}
</div>
</main>
<footer className="footer">This is copy right of no one except for images :)</footer>

</div>
);}
}
export default App;

Todo组件:

import React, { useState } from 'react'
function Todo(props){
const [width,setWidth]=useState(140);
const [height,setHeight]=useState(85);
return(
<div className="todo-item">
<p style={{display : 'none'}}>{props.todo.id}</p>
<p>{props.todo.text}</p>
<input type="checkbox" checked={props.todo.completed}

onChange={()=>{props.handleChange(props.todo.id)}}

/>
<img 
// onMouseOver={(e)=>{setWidth(250);setHeight(250);}} 
// onMouseOut={(e)=>{setWidth(140);setHeight(85);}}
src={props.todo.imageUrl} width={width} height={height}/>
<hr />
</div>
);
}
export default Todo;

您可以尝试使if条件内联,这样就不会使用return。类似于:

handleChange (id){
this.setState((prevState)=>{
const todos = prevState.myTodos.map(item => 
(item.id === id) ? {...item, completed: !item.completed} : item )
})
}

已编辑:此解决方案之所以有效,是因为它使用扩展语法{...item, completed: !item.completed}返回了一个新的JS对象。反过来,这将强制执行新的渲染调用。

请检查此片段

import React, { Component } from "react";
import "./styles.css";
class App extends Component {
state = {
myTodos: [
{ id: 1, title: "wake up", completed: false },
{ id: 2, title: "brush", completed: false }
]
};
handleChange = (id) => {
this.setState((prevState) => ({
myTodos: prevState.myTodos.map((todo) => {
if (todo.id === id) {
return { ...todo, completed: !todo.completed };
}
return todo;
})
}));
};
render() {
return (
<div className="App">
<h1>TODOS</h1>
{this.state.myTodos.map((todo) =>
todo.completed ? (
<del>
<p onClick={() => this.handleChange(todo.id)}>{todo.title}</p>
</del>
) : (
<p onClick={() => this.handleChange(todo.id)}>{todo.title}</p>
)
)}
</div>
);
}
}
export default App;

工作代码沙盒

问题

  1. 您没有在真实条件下返回对象

最新更新