React: How to navigate through list by arrow keys

前端 未结 3 1647
耶瑟儿~
耶瑟儿~ 2020-12-07 13:47

I have build a simple component with a single text input and below of that a list (using semantic ui).

Now I would like to use the arrow keys to navigate through the

3条回答
  •  萌比男神i
    2020-12-07 14:01

    The accepted answer was very useful to me thanks! I adapted that solution and made a react hooks flavoured version, maybe it will be useful to someone:

    import React, { useState, useEffect } from "react";
    import ReactDOM from "react-dom";
    
    const useKeyPress = function(targetKey) {
      const [keyPressed, setKeyPressed] = useState(false);
    
      function downHandler({ key }) {
        if (key === targetKey) {
          setKeyPressed(true);
        }
      }
    
      const upHandler = ({ key }) => {
        if (key === targetKey) {
          setKeyPressed(false);
        }
      };
    
      React.useEffect(() => {
        window.addEventListener("keydown", downHandler);
        window.addEventListener("keyup", upHandler);
    
        return () => {
          window.removeEventListener("keydown", downHandler);
          window.removeEventListener("keyup", upHandler);
        };
      });
    
      return keyPressed;
    };
    
    const items = [
      { id: 1, name: "Josh Weir" },
      { id: 2, name: "Sarah Weir" },
      { id: 3, name: "Alicia Weir" },
      { id: 4, name: "Doo Weir" },
      { id: 5, name: "Grooft Weir" }
    ];
    
    const ListItem = ({ item, active, setSelected, setHovered }) => (
      
    setSelected(item)} onMouseEnter={() => setHovered(item)} onMouseLeave={() => setHovered(undefined)} > {item.name}
    ); const ListExample = () => { const [selected, setSelected] = useState(undefined); const downPress = useKeyPress("ArrowDown"); const upPress = useKeyPress("ArrowUp"); const enterPress = useKeyPress("Enter"); const [cursor, setCursor] = useState(0); const [hovered, setHovered] = useState(undefined); useEffect(() => { if (items.length && downPress) { setCursor(prevState => prevState < items.length - 1 ? prevState + 1 : prevState ); } }, [downPress]); useEffect(() => { if (items.length && upPress) { setCursor(prevState => (prevState > 0 ? prevState - 1 : prevState)); } }, [upPress]); useEffect(() => { if (items.length && enterPress) { setSelected(items[cursor]); } }, [cursor, enterPress]); useEffect(() => { if (items.length && hovered) { setCursor(items.indexOf(hovered)); } }, [hovered]); return (

    Use up down keys and hit enter to select, or use the mouse

    Selected: {selected ? selected.name : "none"} {items.map((item, i) => ( ))}
    ); }; const rootElement = document.getElementById("root"); ReactDOM.render(, rootElement);

提交回复
热议问题