Tengo el componente SearchBar así:

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

Y botones así:

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

Ahora quiero agregar un código que para cada actualización de componente verifique qué página del usuario está.

-

Entonces, si el usuario está en la página número uno (this.state.page === 1) this.state.prevButton debería ser siempre falso, pero para todas las demás páginas this.state.prevButton debería ser siempre verdadero.

this.state.nextButton debe ser falso solo cuando this.state.page === 10

Solo necesito navegar entre la página 1 y la 10.

-

¿Qué métodos de ciclo de vida de React serían suficientes para esa funcionalidad?


Probé algo así pero no es bueno, no está claro, es desordenado y no funciona ...

  componentDidUpdate(prevProps) {

    if (this.props !== prevProps) {

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

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

    }

  }

ACTUALIZACIÓN:


Si ve una mejor manera de hacer esto, por favor comparta sus pensamientos

Código completo de ese componente:

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);
0
MountainConqueror 23 feb. 2018 a las 01:55

2 respuestas

La mejor respuesta

Alternativamente, puede deshabilitar los botones basados en page de la siguiente manera:

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>

No estoy seguro de cómo está deshabilitando el siguiente botón, pero sustituya x arriba con el número de páginas.

2
Anthony 22 feb. 2018 a las 23:14

Con respecto a su pregunta sobre 'qué método de ciclo de vida', sugeriría usar componentWillReceiveProps si está verificando si algo debe volver a renderizarse en función de los cambios de accesorios. Compararía this.props con nextProps (pasaría nextProps como argumento a componentWillReceiveProps) en ese método y realizaría una acción basada en eso.

Sin embargo, si solo está tratando de determinar si habilitar / deshabilitar botones, puede usar lo siguiente en la propiedad 'deshabilitada' de los botones.

Es decir, para el botón 'anterior'

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

Y para el botón 'siguiente'

disabled={this.state.page === 10}
0
Michael Goetti 22 feb. 2018 a las 23:13