Добавление не работает должным образом в Reactjs

#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 .