@Sanchik97

Почему удаляется последний элемент из массива в state?

Добрый день! Есть два компонента, в одном из которых кнопка, которая по клику вызывает второй компонент. Компонент может быть вызван несколько раз, поэтому он лежит в массиве state. Внутри второго компонента есть кнопка удалить. Но при нажатии удаляется не выбранный элемент, а последний в массиве. Почему так происходит?

Первый компонент:
spoiler
import React from 'react'
import { AnswerInput } from '../AnswerInput/AnswerInput'

class QuestionInput extends React.Component {
	state = {
		answers: []
	}

	removeAnswerHandler = index => {
		this.state.answers.splice(index, 1)
		this.setState({
			answers: this.state.answers
		})
	}

	addAnswerInputHandler = () => {
		this.setState({
			answers: [
				...this.state.answers,
				<AnswerInput removeAnswerHandler={this.removeAnswerHandler} />
			]
		})
	}

	render() {
		return (
			<div>
				{this.state.answers.map((item, index) => (
					<div key={index}>{item}</div>
				))}
				<div className="mt-3 mb-3 ml-2">
					<p className="link  text-secondary">
						<i
							className="fas fa-plus"
							onClick={() => this.addAnswerInputHandler()}
						/>
					</p>
				</div>
			</div>
		)
	}
}

export default QuestionInput


Второй компонент:

spoiler
import React from 'react'
import { Input } from 'reactstrap'

export class AnswerInput extends React.Component {
	render() {
		return (
			<div className="d-flex align-items-center">
				<Input
					className="answerinput"
					placeholder="Ответ клиента"
					defaultValue=""
				/>
				<i
					className="far fa-trash-alt link ml-2 mr-2 text-secondary"
					onClick={index => {
						this.props.removeAnswerHandler(index)
					}}
				/>
				<i className="far link ml-2 mr-2 fa-copy text-secondary" />
			</div>
		)
	}
}

  • Вопрос задан
  • 94 просмотра
Решения вопроса 1
@forspamonly2
удаляется не то, что вы хотели, потому что вы нигде не передаёте тот index. обработчик события получает параметром объект события, так что в вашем onClick={index => { совсем не индекс там приходит.
а почему последний - ума не приложу, вроде бы должен первый.

в любом случае, вы что-то не то делаете. складировать компоненты с полями ввода в массиве не нужно. вы же наверное как-то оттуда значения получать собираетесь? храните в массиве сами введённые значения, второй свой компонент переделайте на функциональный, а в основном компоненте мапьте на него те значения и индексы.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
mironovbam
@mironovbam
Фронтендер
Как было уже сказано, первым аргументом передается объект события.

Я бы лично немного изменил render метод перового компонента. Что-то вроде такого:
{this.state.answers.map((item, index) => (
  <AnswerInput removeAnswerHandler={() => this.removeAnswerHandler(index)} />
))}
Ответ написан
@halfcupgreentea
Проблема в key. У вас используется индекс и он конечно съезжает при вырезании элементов посередине. Почитайте про то, для чего он нужен и как работает в документации по реакту.
Решение: храните в state не компоненты а какие нибудь уникальные числа для каждого аудио инпута, используйте эти уникальные числа в качестве key
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
Ultimate Guitar Калининград
от 1 000 до 5 000 usd.
Enapter Санкт-Петербург
от 160 001 руб.
Spar-online Нижний Новгород
от 150 000 до 170 000 руб.