Warm tip: This article is reproduced from serverfault.com, please click

Addition is not working properly in Reactjs

发布于 2020-11-30 19:17:33

I'm new to react here is my code, having 3 buttons restart, previous and next. I'm passing some data through props in array form which I need to display in slides. Whenever I click on next the next element in the array should be print, and after the last element the next button should be disabled and after the first element, the previous button should be disabled. To achieve this I'm using prev and next functions where I'm increasing and decreasing the value of state in n. my problem is whenever I'm pressing next my data is changing but the value remains the same, I'm very confused about how is this possible as I'm using the value of n while displaying too. Similarly while pressing previous the data is changing but the value of n is not changing.


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;

Could anyone please help me with this?

Questioner
Pooja Kushwah
Viewed
0
Dean James 2020-12-01 06:03:51

So there's a few things you can do to avoid render issues here. First, you should avoid calling anything on the document because a rerender will remove your previous actions against it.

If you have all your buttons respect the state, then you can enable/disable them easily:

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>
    );
  }
}

Also, you can check the length property of the slides prop instead of hardcoding 4 :)