Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: How to navigate through list by arrow keys

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 list.

  • First of all I have to select the first element. But how do I access a specific list element?
  • Second I would get the information of the current selected element and select the next element. How do I get the info which element is selected?

Selection would mean to add the class active to the item or is there a better idea for that?

export default class Example extends Component {     constructor(props) {         super(props)         this.handleChange = this.handleChange.bind(this)         this.state = { result: [] }     }     handleChange(event) {         // arrow up/down button should select next/previous list element     }     render() {         return (             <Container>                 <Input onChange={ this.handleChange }/>                 <List>                     {                         result.map(i => {                             return (                                 <List.Item key={ i._id } >                                     <span>{ i.title }</span>                                 </List.Item>                             )                         })                     }                 </List>             </Container>         )     } } 
like image 372
user3142695 Avatar asked Feb 04 '17 05:02

user3142695


People also ask

Can you use arrow functions in React?

Learn more at the React docs. If you use arrow functions within render , each call to render will create new function objects. If you then pass these functions to child elements via props , optimizations based on PureComponent or shouldComponentUpdate will fail (as the arrow function props will change on every render).

How do you display a list of objects in React?

Displaying items from a list of objects in React is very simple. We can iterate over a list of objects using the . map() method in React JSX. Here is the example in which we mapped a list of objects and displayed them in the React app.


1 Answers

Try something like this:

export default class Example extends Component {   constructor(props) {     super(props)     this.handleKeyDown = this.handleKeyDown.bind(this)     this.state = {       cursor: 0,       result: []     }   }    handleKeyDown(e) {     const { cursor, result } = this.state     // arrow up/down button should select next/previous list element     if (e.keyCode === 38 && cursor > 0) {       this.setState( prevState => ({         cursor: prevState.cursor - 1       }))     } else if (e.keyCode === 40 && cursor < result.length - 1) {       this.setState( prevState => ({         cursor: prevState.cursor + 1       }))     }   }    render() {     const { cursor } = this.state      return (       <Container>         <Input onKeyDown={ this.handleKeyDown }/>         <List>           {             result.map((item, i) => (               <List.Item                 key={ item._id }                 className={cursor === i ? 'active' : null}               >                 <span>{ item.title }</span>               </List.Item>             ))           }         </List>       </Container>     )   } } 

The cursor keeps track of your position in the list, so when the user presses the up or down arrow key you decrement/increment the cursor accordingly. The cursor should coincide with the array indices.

You probably want onKeyDown for watching the arrow keys instead of onChange, so you don't have a delay or mess with your standard input editing behavior.

In your render loop you just check the index against the cursor to see which one is active.

If you are filtering the result set based on the input from the field, you can just reset your cursor to zero anytime you filter the set so you can always keep the behavior consistent.

like image 99
shadymoses Avatar answered Sep 23 '22 02:09

shadymoses