나는 반응으로 todoapp을 만들고 있는데, 확인란을 클릭해도 아무 일도 일어나지 않습니다. 이 문제에 대한 해결책을 얻지 못하고 있습니다. 내 코드는 다음과 같습니다.
App.js
import './App.css';
import React from 'react'
import TodoItem from './components/TodoItem'
import todosData from './components/TodoList'
class App extends React.Component {
constructor() {
super()
this.state = {
todos : todosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed
}
console.log(todo)
return todo
})
return {
todos : updatedTodos
}
})
}
render() {
const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item}
handleChange={this.handleChange} />)
return (
<div className='todo-list'>
{todoItems}
</div>
);
}
}
export default App;
TodoItem.js
import React from 'react'
function TodoItem(props) {
return (
<div className='todo-item'>
<input type='checkbox'
checked={props.item.completed}
onChange={() =>{props.handleChange(props.item.id)}}
/>
<p>{props.item.text}</p>
</div>
)
}
export default TodoItem
TodoList.js
const todosData = [
{
id : 1,
text : "Take Out the trash",
completed : false
},
{
id : 2,
text : "Grocery shopping",
completed : false
},
{
id : 3,
text : "Mow lawn",
completed : false
},
{
id : 4,
text : "Clean toilet",
completed : true
},
]
export default todosData
나머지 API 응답을 모방하기 위해 사전으로 TodoList.js 에서 데이터를 받고 있습니다 . 문제가 무엇인지 모르겠습니다. 반응이 처음입니다. 코드에 문제가 있습니까?
반응 버전 : 17.0.1
귀하의 코드에서 볼 수있는 한 가지 문제 handleChange
는 App
구성 요소 상태 메서드 에서 prevState.todos.map
. 즉,
handleChange(id) {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed //--> Here the state is getting mutated.
}
//...rest of the code
여기에서는 배열에서 사용
Array.map
하고todos
있지만todo
맵의 각각 은 여전히 동일한 참조를 가지므로 상태todo.completed = !todo.completed
의todos
배열이 업데이트 될 때 . 예측할 수없는 문제가 발생할 수 있습니다.
그래서 우리는 그 handleChange
방법을 아래와 같이 변환 할 수 있습니다.
handleChange(id) {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
return {
...todo,
...(todo.id === id && {
completed: !todo.completed
})
}
})
return {
todos: updatedTodos
}
})
}
아래는 실행 가능한 스 니펫입니다.
const todosData = [{id:1,text:"Take Out the trash",completed:false},{id:2,text:"Grocery shopping",completed:false},{id:3,text:"Mow lawn",completed:false},{id:4,text:"Clean toilet",completed:true}]
const {Component} = React;
function TodoItem(props) {
return (
<div className='todo-item'>
<input type='checkbox'
checked={props.item.completed}
onChange={() =>{props.handleChange(props.item.id)}}
/>
<p>{props.item.text}</p>
</div>
)
}
class App extends Component {
constructor() {
super()
this.state = {
todos: todosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
return {
...todo,
...(todo.id === id && {completed: !todo.completed})
}
})
return {
todos: updatedTodos
}
})
}
render() {
const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item}
handleChange={this.handleChange} />)
return (
<div className='todo-list'>
{todoItems}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="react"></div>
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다