1

I'd like to create a menu based on a 2 dimensional Array: title and icon name.
Here's what I tried:

class Menu2 extends React.Component{
  constructor(props) {
   super(props);
   this.state = { Items: [['Home','home'],['User','user'],['Messages','envelope'], ['Finances','wallet'], ['Meal','silverware-fork-knife']]}
 }

 render(){
   <View style={styles.menu}>
   {this.state.Items.map((Items,i) => {
     return(
       <TouchableOpacity style={[styles.menu_item,styles.menu_item]} onPress={() => {this.props.navigation.navigate(Items[i][0]);}}>
       <FontAwesome name={Items[i][1]} size={40} color="#fff"/>
         <Text style={styles.menu_text}>{Items[i][0]}</Text>
       </TouchableOpacity>
     )
   })};
    </View>
 }
}

export default Menu2

Error returned is "TypeError undefined is not an object (evaluating 'Items[i][1]')"

What I was expecting is that "i" would by the iteration 0, 1, 2, 3, 4 (looping 5 times in my case) of my array and so Items[i][0] = the title and Items[i][1] = the icon name. But I couldn't make it work like I would have liked.

Any ideas?

2 Answers 2

1

You're using .map incorrectly!

The MDN documentation for Array.prototype.map() shows how to use the callback for this

function callback(currentValue, index, array)

Your callback this.state.Items.map((Items,i) => puts the currentValue into a variable named Items, but then you use Items as if it were the full array!

Solution

Try this instead:

   {this.state.Items.map((currentItem) => {
     return(
       <TouchableOpacity style={[styles.menu_item,styles.menu_item]} onPress={() => {this.props.navigation.navigate(currentItem[0]);}}>
       <FontAwesome name={currentItem[1]} size={40} color="#fff"/>
         <Text style={styles.menu_text}>{currentItem[0]}</Text>
       </TouchableOpacity>
     )
   })};
Sign up to request clarification or add additional context in comments.

4 Comments

Ok thanks it seems to work better now but I can't manage to import it somewhere else, for example on my home page I've import Menu2 from './Menu' then further in render() I call it: <Menu2 navigation={this.props.navigation} /> it gets me Invariant Violation: Menu2(...) Nothing was returned from render.
@sNNNk that's a different problem, it's because you have no return statement in your render() function. Add return ( line at the top of the function, above <View>, then close the ) at the end of the function. That should fix it.
It's better, but I've still an error "Text strings must be rendered within <Text> component." I can't find where is the error
@sNNNk Since the problem you initially posted about has been resolved, it might be better accept the answer here and post a new question. I don't necessarily know the answer to your new problem and nobody else will be able to see it if it is posted here in the comments.
0

It should be Items[0]

      <FontAwesome name={Items[1]} size={40} color="#fff"/>
         <Text style={styles.menu_text}>{Items[0]}</Text>
       </TouchableOpacity>

check this working codesandbox https://codesandbox.io/s/proud-cache-gyuge

1 Comment

Ok thanks, wasnt using map correctly, it seems to work better now but I can't manage to import it somewhere else, for example on my home page I've import Menu2 from './Menu' then further in render() I call it: <Menu2 navigation={this.props.navigation} /> it gets me Invariant Violation: Menu2(...) Nothing was returned from render.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.