Reputation: 577
I have a variable called assignee
. Assignee can be one of the three names I listed below in the array. On startup I call a API that returns the current assignee (if an assignee exists). I set the assignee variable to the name I received from the API.
I have a div
element that displays the assignee name, when a user clicks this element I want the assignee to change according to the list order. How do I solve this?
Lets say I get Sara
from the Api, now when I click the element I want assignee to change to Bill
then to Steve
, then to Sara
. It should go back to the start of the array and re-iterate. Is this the best approach to this problem or are there better ways to solve this?
const users = ["Bill", "Steve", "Sara"];
const [assignee, setAssignee] = useState<string>();
..
const handleAssigneeOnClick = () => {
setAssignee(users[0]);
};
..
<div
className="assignee"
onClick={() => {
handleAssigneeOnClick();
}}
>
<p>{assignee}</p>
</div>
Upvotes: 0
Views: 3825
Reputation: 59511
You could alter the assignee
state variable to instead hold the index for the corresponding person in the array. Like this:
const [assignee, setAssignee] = useState<number>(-1);
const handleAssigneeOnClick = () => {
setAssignee(prev => (prev + 1) % 3);
};
This sets the index to be the remainder of the division of the index + 1 by 3. You could also do users.length
for something more dynamic, should your array grow.
And then in your return, display the name like this:
<div
className="assignee"
onClick={handleAssigneeOnClick}
>
<p>{users[assignee]}</p>
</div>
I set the initial state value to -1
because you seem to have had the initial string empty until click. You can change this obviously to 0 if you want someone assigned by default.
Working example:
const users = ["Bill", "Steve", "Sara"];
const App = () => {
const [assignee, setAssignee] = React.useState(-1);
const handleAssigneeOnClick = () => {
setAssignee(prev => (prev + 1) % 3);
};
return (
<div
className="assignee"
onClick={handleAssigneeOnClick}
>
<p>{users[assignee]}</p>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'));
div {
background: red;
height: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Upvotes: 1
Reputation: 14365
I would structure it a little differently and store the index in state.
It checks to see if the current index is the last one, and moves back to the beginning if so. Otherwise, it just adds one.
Then you use the index to print the current selected user.
const {useState, useEffect} = React;
const users = ["Bill", "Steve", "Sara"];
const Example = () => {
const [selected, setSelected] = useState(0);
const handleAssigneeOnClick = () => {
setSelected(prev => {
if (prev === users.length - 1) {
return 0;
} else {
return prev + 1;
}
});
};
return (
<div onClick={handleAssigneeOnClick}>
<p>{users[selected]}</p>
</div>
)
}
ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 1