哪个React生命周期方法用于控制按钮状态(启用/禁用)?

时间:2018-02-22 22:55:07

标签: javascript reactjs

我有SearchBar组件,如此:

class SearchBar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      term: '',
      page: 1,
      prevButton: false,
      nextButton: true,
    };

和按钮一样:

<div>
      <button
        className="btn btn-secondary"
        onClick={this.handlePrev}
        disabled={!this.state.prevButton}
      >
        Prev Page
      </button>
      <span className="SearchBar-page-numbers">{this.state.page}</span>
      <button
        className="btn btn-secondary"
        onClick={this.handleNext}
        disabled={!this.state.nextButton}
      >
        Next Page
      </button>
    </div>

现在我想为每个组件更新添加的代码将检查用户的哪个页面。

-

因此,如果用户位于第一页(this.state.page === 1this.state.prevButton,则应始终为false,但对于每个其他页面this.state.prevButton应始终为true。

仅当this.state.nextButton

时,

this.state.page === 10才应为false

我只需要在第1页到第10页之间进行导航。

-

React生命周期方法 对于该功能是否足够?

我尝试了类似的东西,但它不好,不清楚,凌乱而且不起作用......

  componentDidUpdate(prevProps) {

    if (this.props !== prevProps) {

      if (this.state.page === 1) {
        this.setState({ prevButton: false });
      }

      if (this.state.page !== 1) {
        this.setState({ prevButton: true });
      }

    }

  }

更新

如果您看到更好的方法,请分享您的想法!

该组件的完整代码:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {
  wakeUpHerokuServerFromSleep,
  fetchRecipesAndPage,
  loadRecipes,
  showClickedInfo,
  addLocalStorageToFavoritesList,
} from '../../actions/';
import './style.css';

import ButtonSearch from '../../components/ButtonSearch';

class SearchBar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      term: '',
      page: 1,
      prevButton: false,
      nextButton: true,
    };

    this.handlePrev = this.handlePrev.bind(this);
    this.handleNext = this.handleNext.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    this.props.wakeUpHerokuServerFromSleep();
    const localStorageData = JSON.parse(
      localStorage.getItem('lastSavedFavourites')
    );
    if (localStorageData) {
      this.props.addLocalStorageToFavoritesList(localStorageData);
    }
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props !== prevProps) {
      this.setState({ term: this.props.showClickedInfoFromStore });
      this.checker(this.props);
    }

    const { page } = this.state;
    if (prevState.page !== page) {
      this.setState({ prevButton: page !== 1 });
    }
  }

  // If some ingredient was manually selected
  // go to page 1 of that ingredient
  checker(properties) {
    if (properties.manualSelectionFromStore) {
      this.setState({ page: 1 });
    }
  }

  // If input was changed go to page 1
  handleInputChange(event) {
    this.setState({ page: 1 });
    this.setState({ term: event.target.value });
  }

  // After submit, go to page 1 and fetch data
  handleSubmit(event) {
    this.setState({ page: 1 });
    if (this.state.term === '') {
      event.preventDefault();
      this.props.showClickedInfo('');
    } else {
      event.preventDefault();
      this.props.fetchRecipesAndPage(this.state.term, 1);
      this.props.showClickedInfo(this.state.term);
    }
  }

  handlePrev() {
    let newPage = this.state.page - 1;
    if (newPage <= 0) {
      newPage = 1;
    }
    this.setState({ page: newPage });
    this.props.loadRecipes(newPage);
  }

  handleNext() {
    let newPage = this.state.page + 1;
    if (newPage >= 10) {
      newPage = 10;
    }
    this.setState({ page: newPage });
    this.props.loadRecipes(newPage);
  }

  buttonsView() {
    // Show navigation buttons (prev, next):
    // If there is an error coming from server
    // OR
    // If current search isn't null AND app has found some data and successfully fetched it
    if (
      this.props.error ||
      (this.props.currentSearchFromStore !== null &&
        this.props.checkIfSomeDataWasFound)
    ) {
      return (
        <div>
          <button
            className="btn btn-secondary"
            onClick={this.handlePrev}
            disabled={!this.state.prevButton}
          >
            Prev Page
          </button>
          <span className="SearchBar-page-numbers">{this.state.page}</span>
          <button
            className="btn btn-secondary"
            onClick={this.handleNext}
            disabled={!this.state.nextButton}
          >
            Next Page
          </button>
        </div>
      );
    }
    // Esle return just <div />
    return <div />;
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit} className="SearchBar-input-group">
          <input
            className="form-control"
            placeholder={this.props.showClickedInfoFromStore}
            value={this.state.term}
            onChange={this.handleInputChange}
          />
          <ButtonSearch className="btn btn-secondary submit">
            Search
          </ButtonSearch>
        </form>
        <div className="SearchBar-pagination-buttonsView">
          {this.buttonsView()}
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    error: state.error,
    currentSearchFromStore: state.currentSearchTerm,
    checkIfSomeDataWasFound: state.checkRecipesData,
    showClickedInfoFromStore: state.showClickedInfo,
    manualSelectionFromStore: state.manualSelection,
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(
    {
      wakeUpHerokuServerFromSleep,
      fetchRecipesAndPage,
      loadRecipes,
      showClickedInfo,
      addLocalStorageToFavoritesList,
    },
    dispatch
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);

2 个答案:

答案 0 :(得分:2)

或者,您可以根据page禁用按钮,如下所示:

const { page } = this.state;

<div>
  <button
    className="btn btn-secondary"
    onClick={this.handlePrev}
    disabled={page === 1}
  >
    Prev Page
  </button>
  <span className="SearchBar-page-numbers">{this.state.page}</span>
  <button
    className="btn btn-secondary"
    onClick={this.handleNext}
    disabled={page === x}
  >
    Next Page
  </button>
</div>

我不确定你是如何禁用下一个按钮的,但是将上面的x替换为页数。

答案 1 :(得分:0)

关于你的“生命周期方法”问题,如果你要根据道具变化检查某些东西是否应该重新渲染,我建议使用componentWillReceiveProps。您将this.props与该方法中的nextProps(传入nextProps作为componentWillReceiveProps的参数)进行比较,并根据该方法执行操作。

但是,如果您只是想确定是否启用/禁用按钮,则可以在按钮的“禁用”属性中使用以下内容。

即。对于“上一个”按钮

disabled={this.state.page === 1}

和“下一步”按钮

disabled={this.state.page === 10}