#javascript #reactjs
#javascript #reactjs
Вопрос:
Мое приложение React работает не так, как должно быть. Проблема в том, что флажки вообще не меняются. Мне удалось показать флажки (те, у которых есть свойство completed=true ), и при отладке кажется, что при нажатии он работает нормально, но по какой-то причине поле, которое необходимо изменить, автоматически изменяется само по себе.
У вас есть какие-либо идеи, почему?
//APP.JS
import React from "react"
import './App.css';
import Header from "./Header"
import TodoItem from "./todoItem";
import todosData from "./todosData"
class App extends React.Component {
constructor() {
super()
this.state = {
todos: todosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
this.setState((prevState) => {
const newArray = prevState.todos.map((elem) => {
if(elem.id === id) {
elem.completed = !(elem.completed)
}
return elem
})
return {
todos: newArray
}
})
}
render() {
const todosArray = this.state.todos.map(item =>
<TodoItem
key={item.id}
item={item}
handleChange={this.handleChange}
/>)
return (
<div className="App">
<Header />
<div className="container">
{todosArray}
</div>
</div>
)
}
}
export default App;
//TODOITEM.JS
import React from "react"
function TodoItem(props) {
return (
<div className="elem-container">
<input type="checkbox"
checked={props.item.completed}
onChange={() => props.handleChange(props.item.id)}
/>
<span className="span-container">{props.item.text}</span>
</div>
)
}
export default TodoItem
//TODOSDATA.JS
const todosData = [
{
id: 1,
text: "Take out the trash",
completed: true
},
{
id: 2,
text: "Grocery shopping",
completed: false
},
{
id: 3,
text: "Clean gecko tank",
completed: false
},
{
id: 4,
text: "Mow lawn",
completed: true
},
{
id: 5,
text: "Catch up on Arrested Development",
completed: false
}
]
export default todosData
Заранее благодарю вас за помощь
Ответ №1:
вам нужно изменить две вещи, и сначала все будет работать нормально: внутри todoItem.js
onChange={(e) => props.handleChange(e,props.item.id)}
второе:
внутри родительского файла
handleChange(event, id) {
this.setState((prevState) => {
const newArray = prevState.todos.map((elem) => {
if(elem.id === id) {
elem.completed = event.target.checked
}
return elem
})
return {
todos: newArray
}
})
}
теперь все будет работать так, как вы ожидали
, хорошего дня
Ответ №2:
Я не эксперт, поскольку сам изучаю React, но, глядя на код handleChange (id), в его операторе ‘if’ нет состояния else, вы пробовали добавлять?
Ответ №3:
Добавив к ответу @mouheb, вы можете упростить еще один шаг. вам не нужно map
использовать все элементы для обновления одного элемента. вы можете изменить непосредственно элемент (если он изменяемый).
// todoItem.js
onChange={(e) => props.handleChange(e, props.item) }
// parent file
handleChange(event, prop) {
prop.completed = event.target.
this.setState({ todos: this.state.todos }) or this.setState({ todos: [...this.state.todos] })
}