I've got the following search suggest with React hooks that uses react-hotkeys-hooks
to manage keypress.
Why does selectedUserItem
not update on keypress Enter ? It stays 0 while the up and down keys change.
import { useHotkeys } from "react-hotkeys-hook";
import React, { useState } from "react";
import "./styles.css";
const itemsByName = [
{
id: 1,
name: "Ice Cream"
},
{
id: 2,
name: "Banana Pudding"
},
{
id: 3,
name: "Chocolate Cake"
},
{
id: 4,
name: "Sponge Cake"
},
{
id: 5,
name: "Carrot Cake"
}
];
const App = () => {
const [selectedUserItem, setSelectedUserItem] = useState(0);
// const [create] = useMutation(SAVE_USER_ITEM, {
// refetchQueries: ["UserItemsQuery"]
// })
const itemSelect = (e, item) => {
e.preventDefault();
// create({ variables: { input: { id: item.id } } });
// console.log(item)
};
const increment = selectedUserItem => {
const max = itemsByName.length - 1;
return max > selectedUserItem ? selectedUserItem + 1 : max;
};
const decrement = selectedUserItem => {
const min = 0;
return min < selectedUserItem ? selectedUserItem - 1 : min;
};
useHotkeys(
"*",
(event, handler) => {
// console.log(handler)
switch (event.key) {
case "ArrowDown":
setSelectedUserItem(selectedUserItem => increment(selectedUserItem));
break;
case "ArrowUp":
setSelectedUserItem(selectedUserItem => decrement(selectedUserItem));
break;
case "Enter":
console.log(selectedUserItem);
const userItem = itemsByName[selectedUserItem];
console.log(userItem);
break;
default:
console.log(event.key);
break;
}
},
{
filter: () => true
}
);
return (
<div className="absolute w-3/4 mt-16 ml-8 py-2 bg-white shadow-xl rounded-lg">
<h1>Index: {selectedUserItem}</h1>
{itemsByName.map((item, i) => {
return (
<div
href="#"
onClick={e => itemSelect(e, item)}
className={`${selectedUserItem === i ? "hovered" : ""} dessert`}
key={item.id}
>
{item.id}: {item.name}
</div>
);
})}
</div>
);
};
export default App;
useHotkeys
internals use the useCallback
and useEffect
hooks, which need to know when some of its dependencies change. To make sure it works well with these hooks,useHotkeys
offers to pass a deps
array , like the other hooks mentioned, as its last parameter.
deps: any[] = []
: The dependency array that gets appended to the memoization of the callback. Here you define the inner dependencies of your callback. If for example your callback actions depend on a referentially unstable value or a value that will change over time, you should add this value to yourdeps
array. Since most of the time your callback won't depend on any unstable callbacks or changing values over time you can leave this value alone since it will be set to an empty array by default.
In your code, it would looks like this:
// These never changes and do not rely on the component scope, so they
// can be defined safely outside the component.
const increment = selectedUserItem => {
const max = itemsByName.length - 1;
return max > selectedUserItem ? selectedUserItem + 1 : max;
};
const decrement = selectedUserItem => {
const min = 0;
return min < selectedUserItem ? selectedUserItem - 1 : min;
};
const App = () => {
const [selectedUserItem, setSelectedUserItem] = useState(0);
useHotkeys(
"*",
(event, handler) => {
switch (event.key) {
case "ArrowDown":
setSelectedUserItem(increment);
break;
case "ArrowUp":
setSelectedUserItem(decrement);
break;
case "Enter":
console.log(selectedUserItem, itemsByName[selectedUserItem]);
break;
default:
console.log(event.key);
break;
}
},
{
filter: () => true
},
// The dependencies array which ensure that the data is up to date in the callback.
[selectedUserItem, setSelectedUserItem]
);
// rest of the component
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.