Пытаюсь изменить элемент массива по методу handleToggle, но возникает ошибка, что я делаю не так, и почему в реакте я все время должен возвращать новый массив?
Дочерний компонент TodoList:
function Todolist(props) {
const todoItem = props.todos.map((todo, index) =>
<ListItem key={todo.id} dense button>
<ListItemIcon>
<Checkbox checked={todo.completed} onChange={props.onChange(todo.id)} edge="start"/>
</ListItemIcon>
<ListItemText primary={todo.title} />
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="comments"></IconButton>
</ListItemSecondaryAction>
</ListItem>
)
return (
<div>
{todoItem}
</div>
)
}
Дочерний компонент FormBox:
function FormBox(props) {
return (
<form onSubmit={props.onSubmit}>
<TextField type="text" variant="filled" className="TextField" fullWidth label="Enter new task" value={props.value} onChange={props.onChange} />
<Button type="submit" size="large" variant="contained">Add</Button>
</form>
)
}
Родительский:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: '',
todos: [
{
title: 'Learn React',
id: Math.random(),
completed: true
}
]
}
};
handleChange = (evt) => {
this.setState({
value: evt.target.value
})
};
handleSubmit = (evt) => {
evt.preventDefault();
const todos = [...this.state.todos];
todos.push({
title: this.state.value,
id: Math.random(),
completed: false
});
this.setState(state => ({
todos,
value: ''
}))
};
handleToggle = (id) => {
const todos = [...this.state.todos];
todos.map(todo => {
if (todo.id === id) {
return todo.completed = !todo.completed
} else {
return todo
}
});
this.setState(state => ({
todos
}))
};
render() {
return (
<div className="App">
<Grid className="Header" justify="center" container>
<Grid item xs={11}>
<h1 className="Title">My to-do react app</h1>
<FormBox value={this.state.value} onSubmit={this.handleSubmit} onChange={this.handleChange}/>
</Grid>
</Grid>
<TodoList todos={this.state.todos} onChange={this.handleToggle} />
</div>
);
}
}
Текст ошибки:
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
документация React предупреждает, что состояние не должно быть напрямую изменено и что все должно проходить через setState.
А на счет неработающего переключателя, вы возвращаете значение свойства элемента return todo.completed = !todo.completed
, т.е. true
или false
, а должны возвращать элемент с измененным свойством
handleSubmit = (evt) => {
evt.preventDefault();
this.setState(state => {
return {
todos: [...state.todos, {title: state.value, id: Math.random(), completed: false}],
value: ''
}
})
};
handleToggle = (id) => {
this.setState(state => {
return {
todos: state.todos.map(todo => todo.id === id ? {...todo, complete: !todo.complete} : todo)
}
})
}
В общем решение было в этом onChange={() => props.onChange(todo.id)}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
При компиляции webpack получаю такую ошибку:
Проблема, собственно, описана в заголовке) Ниже мой кодБуду благодарен за любые идеи
Нужен скрипт, который будет установлен на странице indexhtml и будет на странице /$user_id проверять, есть ли там <div id="reverbs5", если да - то применять...