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);
2 respuestas
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.
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}
Preguntas relacionadas
Nuevas preguntas
javascript
Para preguntas sobre la programación en ECMAScript (JavaScript / JS) y sus diversos dialectos / implementaciones (excepto ActionScript). Incluya todas las etiquetas relevantes en su pregunta; por ejemplo, [node.js], [jquery], [json], etc.