En realidad, quiero mostrar estos nombres en una secuencia, pero cada vez que hago clic en el botón de incremento, el orden (en estado de uso) aumenta en 1, pero cuando hago clic en el botón de disminución por primera vez, el orden vuelve a incrementarse en 1 y luego es menos de uno.
function func() { let [getVal, setVal] = useState({ alerts: "no alerts", order: 0, }); let Names = [ "Default", "Evil laugh", "classic alarm", "Pause", "intro music", "Got item", "Old bounce", "bark", "alarm tone", ]; function slider(e) { let { order } = getVal, value = e.target.id, total = Names.length; if (value === "up" && order !== total - 1) { setVal((rest) => ({ ...rest, order:order + 1 })); } else if (value === "down" && order !== 0) { setVal((rest) => ({ ...rest, order: order - 1 })); } setVal((rest) => ({ ...rest, alerts: Names[order] })); } return ( <> <button onClick={slider} id="up" > up </button> <p> {getVal.alerts} </p> <button onClick={slider} id="down" >down </button> </> ) }Debe realizar el siguiente cambio en su función slider() . Solucionará su problema.
Actualizar el estado en reaccionar es una tarea asíncrona. Lo estabas haciendo tanto dentro como fuera de la condición if. Es por eso que no estaba disminuyendo el orden en el primer clic hacia abajo.
function slider(e) { let { order } = getVal, value = e.target.id, total = Names.length; if (value === "up" && order !== total - 1) { setVal((rest) => ({ ...rest, order:order + 1, alerts: Names[order + 1]})); } else if (value === "down" && order !== 0) { setVal((rest) => ({ ...rest, order: order - 1, alerts: Names[order - 1] })); } }Fragmento de código completo de React:
import React, { useState } from "react"; function func() { let [getVal, setVal] = useState({ alerts: "no alerts", order: 0, }); let Names = [ "Default", "Evil laugh", "classic alarm", "Pause", "intro music", "Got item", "Old bounce", "bark", "alarm tone", ]; function slider(e) { let { order } = getVal, value = e.target.id, total = Names.length; if (value === "up" && order !== total - 1) { setVal((rest) => ({ ...rest, order:order + 1, alerts: Names[order + 1]})); } else if (value === "down" && order !== 0) { setVal((rest) => ({ ...rest, order: order - 1, alerts: Names[order - 1] })); } } return ( <> <button onClick={slider} id="up" > up </button> <p> {getVal.alerts} </p> <button onClick={slider} id="down" >down </button> </> ) }Su controlador no necesita ser tan complicado. También recomendaría usar atributos de datos en lugar de identificadores. He hecho un par de cambios:
A los nombres de las variables para que tengan un poco más de sentido: cuando se habla de matrices index es mejor que order .
Ya no es necesario tener una alerta en estado. Simplemente cargue los nombres en el estado y luego haga que el componente muestre el nombre en el índice actual.
const { Fragment, useEffect, useState } = React; // Pass in the names as a prop function Example({ names }) { // Add the names to state, and initialise the index const [ state, setState ] = useState({ names, index: 0 }); function handleClick(e) { // Get the id from the button's dataset const { id } = e.target.dataset; // Get the names, and index, from state const { names, index } = state; // Create a new index const newIndex = id === 'down' ? index - 1 : index + 1; // Set a new state if the newIndex is between 0 // and less than the names array length if (newIndex >= 0 && newIndex < names.length) { setState({ ...state, index: newIndex }); } } return ( <Fragment> <button data-id="down" onClick={handleClick}>Down</button> <p>{state.names[state.index]}</p> <button data-id="up" onClick={handleClick}>Up</button> </Fragment> ); }; const names=["Default","Evil laugh","classic alarm","Pause","intro music","Got item","Old bounce","bark","alarm tone"]; ReactDOM.render( <Example names={names} />, document.getElementById('react') ); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="react"></div>Aquí hay una versión simplificada de su enfoque.
function func() { let [order, setOrder] = useState(0); let Names = [ "Default", "Evil laugh", "classic alarm", "Pause", "intro music", "Got item", "Old bounce", "bark", "alarm tone" ]; function slider(e) { var action = e.target.id, total = Names.length; if (action === "up" && order !== total - 1) { setOrder( order + 1 ); } else if (action === "down" && order !== 0) { setOrder( order - 1 ); } } return ( <div> <button onClick={slider} id="up"> up </button> <p>{Names[order]}</p> <button onClick={slider} id="down"> down </button> </div> ); }