Search code examples
jsonreact-nativereact-navigationreact-navigation-drawer

Need to dynamically add items into a drawer menu in React Native


I need to have some items dynamically in my app's drawer after some categories get fetched from a json file (https://www.rallyssimo.it/wp-json/wp/v2/categories)

json example (I need that information)

[
  {
    "id": 44,
    .
    .
    "name": "ALTRI RALLY",
    .
    .
  },

Tis is the drawer:

const CustomDrawerComponent = (props) => (
  <SafeAreaView style={{flex:1}}>
    <View style={{height:80, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center'}}>
      <Image
        source={{uri: 'https://www.rallyssimo.it/wp-content/uploads/2016/08/rallyssimo-logo.png'}}
        style={{ height: 60, width: 180}}
      />
    </View>
    <ScrollView>
      <DrawerItems {...props} />
    </ScrollView>
  </SafeAreaView>
)
const AppNavigator = createDrawerNavigator(
  {
    Home: DashboardStackNavigator,
  },
  {
    contentComponent: CustomDrawerComponent
  }
);

const AppContainer = createAppContainer(AppNavigator);


//Main class
export default class App extends React.Component {
  render() {
    return <AppContainer />;
  }
}

How can I put the items (I'm going to get from the JSON) in the drawer?


Solution

  • As you have noticed, you need to create your own custom drawer to achieve this, which is done with contentComponent: CustomDrawerComponent.

    Now you cannot use DrawerItems within CustomDrawerComponent since you want full control on the items listed. But you can recreate the items yourself using basic and elements.

    Finally you need to fetch the API and store the data in your state in order to render the result as a list in the drawer.

    Here is a basic example for :

    import React, { Component } from 'react';
    import { ScrollView, Text, View, Image } from 'react-native';
    import { NavigationActions } from 'react-navigation';
    
    
    class CustomDrawerComponent extends Component {
      constructor(props) {
        super(props);
        this.state = { data: null };
      }
    
      async componentDidMount() {
        fetch('https://www.rallyssimo.it/wp-json/wp/v2/categories')
          .then(res => res.json())
          .then(data => this.setState({ data }))
      }
    
      navigateToScreen(routeName, params) { 
        return () => { this.props.navigation.dispatch(NavigationActions.navigate({ routeName, params })) };
      }
    
      render() {
        if (this.state.data === null) {
          return <Text>...</Text>;
        }
    
        return (
          <View style={{ flex: 1, paddingTop: 30 }}>
            <View style={{height:80, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center'}}>
              <Image
                source={{uri: 'https://www.rallyssimo.it/wp-content/uploads/2016/08/rallyssimo-logo.png'}}
                style={{ height: 60, width: 180}}
              />
            </View>
            <ScrollView>
              <View>
                {this.state.data.map(x => (
                  <Text
                    key={x.id}
                    style={{ fontSize: 16, lineHeight: 30, textAlign: 'center' }}
                    onPress={this.navigateToScreen('page2')}
                  >
                    {x.name}
                  </Text>
                ))}
              </View>
            </ScrollView>
          </View>
        );
      }
    }
    
    
    export default CustomDrawerComponent;
    

    And here is a working snack.