Actually i want to show this Names in a sequence but whenever i click increment button the order ( in useState ) increment by 1 but when i click decrement button first time the order again increment by 1 and then is less than one.
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>
</>
)
}
CodePudding user response:
You need to make the following change in your slider() function. It will fix your issue.
Updating state in react is an asynchronous task. You were doing it both inside and outside the if condition. That's why it was not decrementing the order on first down click.
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] }));
}
}
Full React Code Snippet:
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>
</>
)
}
CodePudding user response:
Your handler doesn't need to be that complicated. I'd also recommend using data-attributes instead of ids. I've made a couple of changes:
To variable names so they make a little more sense - when you're talking about arrays
index
is better thanorder
.There's no longer a need to have an alert in state. Just load the names into state, and then have the component display the name at the current index.
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>
CodePudding user response:
Here is a simplified version of yor approach.
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>
);
}