Reactjs 更新状态的正确位置-React JS

Reactjs 更新状态的正确位置-React JS,reactjs,setstate,react-state,Reactjs,Setstate,React State,我正在React JS中创建一个简单的滑块组件。我有三个按钮重新启动,上一个,下一个。单击上一个按钮将使当前状态递减1,并将继续,直到当前状态等于0。此外,“下一步”按钮将递增状态,直到它等于slides.length-1。滑块对我来说很好,问题是当最后一张幻灯片接近“下一步”按钮时,它仍然处于启用状态,但当我单击它时,它将变为禁用状态。预期的行为是当最后一张幻灯片呈现时,应禁用按钮,而不需要额外单击。“上一步”按钮也存在同样的问题 您可以在此处检查行为: 我敢肯定,更新状态时会出现一些问题,我

我正在React JS中创建一个简单的滑块组件。我有三个按钮重新启动,上一个,下一个。单击上一个按钮将使当前状态递减1,并将继续,直到当前状态等于0。此外,“下一步”按钮将递增状态,直到它等于slides.length-1。滑块对我来说很好,问题是当最后一张幻灯片接近“下一步”按钮时,它仍然处于启用状态,但当我单击它时,它将变为禁用状态。预期的行为是当最后一张幻灯片呈现时,应禁用按钮,而不需要额外单击。“上一步”按钮也存在同样的问题

您可以在此处检查行为:


我敢肯定,更新状态时会出现一些问题,我可能是在错误的位置更新它,这就是不点击我的大脑的原因。

单击“上一步”按钮时,您也会有相同的行为。导出禁用状态可能比试图计算并将其存储在状态中更容易

Slides.js呈现函数

render() {
  const { slides } = this.props;
  return (
    <div>
      <div id="navigation">
        <button
          data-testid="button-restart"
          onClick={this.resandler}
          data-testid="button-restart">
          Restart
        </button>
        <button
          data-testid="button-prev"
          onClick={this.prevHandler}
          data-testid="button-prev"
          // if current slide is 0, there is no previous
          disabled={this.state.currentSlide === 0}>
          Prev
        </button>
        <button
          data-testid="button-next"
          onClick={this.nextHandler}
          data-testid="button-next"
          // if current slide is slides.length - 1, there is no next
          disabled={this.state.currentSlide === this.props.slides.length - 1}>
          Next
        </button>
      </div>
      {slides.map((slide, i) => {
        return i === this.state.currentSlide ? (
          <div id="slide" key={slide + i}>
            <h1 data-testid="title">{slide.title}</h1>
            <p data-testid="text">{slide.text}</p>
          </div>
        ) : null;
      })}
    </div>
  );
}

单击“上一步”按钮时也有相同的行为。导出禁用状态可能比试图计算并将其存储在状态中更容易

Slides.js呈现函数

render() {
  const { slides } = this.props;
  return (
    <div>
      <div id="navigation">
        <button
          data-testid="button-restart"
          onClick={this.resandler}
          data-testid="button-restart">
          Restart
        </button>
        <button
          data-testid="button-prev"
          onClick={this.prevHandler}
          data-testid="button-prev"
          // if current slide is 0, there is no previous
          disabled={this.state.currentSlide === 0}>
          Prev
        </button>
        <button
          data-testid="button-next"
          onClick={this.nextHandler}
          data-testid="button-next"
          // if current slide is slides.length - 1, there is no next
          disabled={this.state.currentSlide === this.props.slides.length - 1}>
          Next
        </button>
      </div>
      {slides.map((slide, i) => {
        return i === this.state.currentSlide ? (
          <div id="slide" key={slide + i}>
            <h1 data-testid="title">{slide.title}</h1>
            <p data-testid="text">{slide.text}</p>
          </div>
        ) : null;
      })}
    </div>
  );
}
在nextHandler中,将设置状态更改为:

this.setState({
      currentSlide: this.state.currentSlide + 1,
      nextDisabled: this.state.currentSlide + 1 === this.props.slides.length -  1,
      prevDisabled: false,
});
考虑到应用程序的简单性,您不需要prevState-您也不需要定义返回中的每个状态字段。react将隐式地将这些字段作为其最后一个值填充:

// This can be just prevState => since you aren't using props
this.setState((prevState, props) => {
  if (prevState.currentSlide < this.props.slides.length - 1) {
    return {
      currentSlide: prevState.currentSlide + 1,
      prevDisabled: false, 
    };
  } else if (prevState.currentSlide === this.props.slides.length - 1) { // Issue is here
    return {
      nextDisabled: true,
      prevDisabled: false, // Don't need to keep defining this
    };
  }
});
前一状态将落后于您的计划1个计数。您需要使用当前状态来执行此操作。因此,另一个解决方案是将其更改为:

prevState.currentSlide + 1 === this.props.slides.length - 1
您可以对prevHandler应用类似的修复。

在nextHandler中,将设置状态更改为:

this.setState({
      currentSlide: this.state.currentSlide + 1,
      nextDisabled: this.state.currentSlide + 1 === this.props.slides.length -  1,
      prevDisabled: false,
});
考虑到应用程序的简单性,您不需要prevState-您也不需要定义返回中的每个状态字段。react将隐式地将这些字段作为其最后一个值填充:

// This can be just prevState => since you aren't using props
this.setState((prevState, props) => {
  if (prevState.currentSlide < this.props.slides.length - 1) {
    return {
      currentSlide: prevState.currentSlide + 1,
      prevDisabled: false, 
    };
  } else if (prevState.currentSlide === this.props.slides.length - 1) { // Issue is here
    return {
      nextDisabled: true,
      prevDisabled: false, // Don't need to keep defining this
    };
  }
});
前一状态将落后于您的计划1个计数。您需要使用当前状态来执行此操作。因此,另一个解决方案是将其更改为:

prevState.currentSlide + 1 === this.props.slides.length - 1

您可以对prevHandler应用类似的修复程序。

代码中的问题是,在检查是否应禁用“上一步”或“下一步”按钮之前,您没有更新当前幻灯片

当按下任何按钮时,首先更新当前幻灯片,然后检查应启用或禁用哪个按钮

nextHandler函数应该如下所示

nextHandler() {
    this.setState(
        prevState => ({ currentSlide: ++prevState.currentSlide}),
        () => {
          if (this.state.currentSlide < this.props.slides.length - 1) {
            this.setState({ prevDisabled: false });
          } else {
            this.setState({ nextDisabled: true });
          }
        }
    );
} 
prevHandler() {
    this.setState(
      prevState => ({ currentSlide: --prevState.currentSlide}),
      () => {
        if (this.state.currentSlide === 0) {
          this.setState({ nextDisabled: false, prevDisabled: true });
        } 
      }
    );
}

代码中的问题是,在检查是否应禁用“上一步”或“下一步”按钮之前,您没有更新currentSlide

当按下任何按钮时,首先更新当前幻灯片,然后检查应启用或禁用哪个按钮

nextHandler函数应该如下所示

nextHandler() {
    this.setState(
        prevState => ({ currentSlide: ++prevState.currentSlide}),
        () => {
          if (this.state.currentSlide < this.props.slides.length - 1) {
            this.setState({ prevDisabled: false });
          } else {
            this.setState({ nextDisabled: true });
          }
        }
    );
} 
prevHandler() {
    this.setState(
      prevState => ({ currentSlide: --prevState.currentSlide}),
      () => {
        if (this.state.currentSlide === 0) {
          this.setState({ nextDisabled: false, prevDisabled: true });
        } 
      }
    );
}

明白了!这是我期待的明确答案,明白了!这是我期待的明确答案。