#javascript #html #arrays #reactjs #dom-events
#javascript #HTML #массивы #reactjs #dom-события
Вопрос:
Я новичок в react, вот мой код, имеющий 3 кнопки перезапуска, предыдущую и следующую. Я передаю некоторые данные через реквизиты в форме массива, которые мне нужно отобразить на слайдах. Всякий раз, когда я нажимаю next, следующий элемент в массиве должен быть print, а после последнего элемента следующая кнопка должна быть отключена, а после первого элемента предыдущая кнопка должна быть отключена. Для достижения этой цели я использую функции prev и next, в которых я увеличиваю и уменьшаю значение состояния n
. моя проблема в том, что всякий раз, когда я нажимаю next, мои данные меняются, но значение остается прежним, я очень смущен тем, как это возможно, поскольку я использую значение n при отображении. Аналогично, при нажатии предыдущего данные меняются, но значение n
не меняется.
import React from "react";
class Slides extends React.Component {
state = {
n: 0,
};
restart = () => {
this.setState({
n: 0,
});
document.getElementById("prev").disabled = true;
document.getElementById("next").disabled = false;
console.log("restart" this.state.n);
};
preveious = () => {
let k = this.state.n - 1;
this.setState({
n: k,
});
if (this.state.n == 0) {
document.getElementById("prev").disabled = true;
}
if (this.state.n < 4) {
document.getElementById("next").disabled = false;
}
console.log("prev" this.state.n);
};
next = () => {
let k = this.state.n 1;
this.setState({
n: k,
});
if (this.state.n == 4) {
document.getElementById("next").disabled = true;
}
if (this.state.n > 0) {
document.getElementById("prev").disabled = false;
}
console.log("next" this.state.n);
};
componentDidMount() {
if (this.state.n == 0) {
document.getElementById("prev").disabled = true;
}
console.log("comp" this.state.n);
}
render() {
return (
<div>
<div id="navigation" className="text-center">
<button
id="restart"
data-testid="button-restart"
className="small outlined"
onClick={this.restart}
>
Restart
</button>
<button
id="prev"
data-testid="button-prev"
className="small"
onClick={this.preveious}
>
Prev
</button>
<button
id="next"
data-testid="button-next"
className="small"
onClick={this.next}
>
Next
</button>
</div>
<div id="slide" className="card text-center">
<h1 data-testid="title">{this.props.slides[this.state.n].title}</h1>
<p data-testid="text">{this.props.slides[this.state.n].text}</p>
{console.log(this.props.slides)}
</div>
</div>
);
}
}
export default Slides;
Может ли кто-нибудь, пожалуйста, помочь мне с этим?
Ответ №1:
Итак, есть несколько вещей, которые вы можете сделать, чтобы избежать проблем с рендерингом здесь. Во-первых, вам следует избегать вызова чего-либо на document
, потому что повторный запуск удалит ваши предыдущие действия против него.
Если все ваши кнопки соответствуют состоянию, вы можете легко включить / отключить их:
class Slides extends React.Component {
constructor() {
super();
this.state = {
n: 0,
};
}
restart = () => {
this.setState({
n: 0,
});
};
previous = () => {
this.setState({
n: this.state.n - 1,
});
};
next = () => {
this.setState({
n: this.state.n 1,
});
};
render() {
return (
<div>
<div id="navigation" className="text-center">
<button
id="restart"
data-testid="button-restart"
className="small outlined"
onClick={this.restart}
>
Restart
</button>
<button
id="prev"
data-testid="button-prev"
className="small"
onClick={this.previous}
disabled={this.state.n === 0}
>
Prev
</button>
<button
id="next"
data-testid="button-next"
className="small"
onClick={this.next}
disabled={this.state.n === this.props.slides.length - 1}
>
Next
</button>
</div>
<div id="slide" className="card text-center">
<h1 data-testid="title">{this.props.slides[this.state.n].title}</h1>
<p data-testid="text">{this.props.slides[this.state.n].text}</p>
{console.log(this.props.slides)}
</div>
</div>
);
}
}
Кроме того, вы можете проверить свойство длины реквизита слайдов вместо жесткого кодирования 4 🙂
Ответ №2:
Я внес несколько логических исправлений в ваш код, и теперь он работает так, как задумано. вы можете проверить себя с помощью этой рабочей ссылки codepen — Working Code
Примечание: одна важная вещь заключается в том, что setState
это асинхронно, хотя вы, возможно, предполагали, что значение n изменится, как только вы вызовете setState
over n, и новое увеличенное значение будет использоваться для сравнения, чего не произошло в вашем случае.
Поэтому я заменил this.state.n
на k
.
Обновленный код —
class Slides extends React.Component {
state = {
n: 0,
};
restart = () => {
this.setState({
n: 0,
});
document.getElementById("prev").disabled = true;
document.getElementById("next").disabled = false;
console.log("restart" this.state.n);
};
preveious = () => {
let k = this.state.n - 1;
this.setState({
n: k,
});
console.log("prev" " n:" this.state.n " k:" k)
if (k == 0) {
document.getElementById("prev").disabled = true;
}
if (k < this.props.slides.length) {
document.getElementById("next").disabled = false;
}
};
next = () => {
let k = this.state.n 1;
this.setState({
n: k,
});
console.log("next" " n:" this.state.n " k:" k);
if (k >= this.props.slides.length-1) {
document.getElementById("next").disabled = true;
}
if (k >= 0) {
document.getElementById("prev").disabled = false;
}
};
componentDidMount() {
if (this.state.n == 0) {
document.getElementById("prev").disabled = true;
}
console.log("comp" this.state.n);
}
render() {
return (
<div>
<div id="navigation" className="text-center">
<button
id="restart"
data-testid="button-restart"
className="small outlined"
onClick={this.restart}
>
Restart
</button>
<button
id="prev"
data-testid="button-prev"
className="small"
onClick={this.preveious}
>
Prev
</button>
<button
id="next"
data-testid="button-next"
className="small"
onClick={this.next}
>
Next
</button>
</div>
<div id="slide" className="card text-center">
<h1 data-testid="title">{this.props.slides[this.state.n].title}</h1>
<p data-testid="text">{this.props.slides[this.state.n].text}</p>
{console.log(this.props.slides)}
</div>
</div>
);
}
}
Ответ №3:
Вы можете использовать свое состояние как
constructor() {
this.state = {
n: 0
};
}
Также я советую вам также сохранить состояния отключения вашей кнопки в массиве. Старайтесь не использовать document
object .