2

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?

Andrea Favero
  • 182
  • 1
  • 15

1 Answers1

2

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.

remeus
  • 2,256
  • 2
  • 10
  • 19
  • It seems work very well, now I've to integrate this in my app. thank you very much – Andrea Favero Jul 31 '19 at 12:36
  • How can I manage to open a "new" Page when clicking in a category? examples: i'm in Dakar, but if i click in ERC nothing happens because they are identified like they're the same page there's m project if it's helpfull for understanding [link](https://snack.expo.io/@daxs96/drawer-navigator-with-dynamic-items) – Andrea Favero Jul 31 '19 at 13:18
  • 1
    You need to change `onPress={this.navigateToScreen('page2')}` to fit your needs. For instance `onPress={this.navigateToScreen(x.name)}` and you make sure the name of the category is the name of the route. – remeus Jul 31 '19 at 13:23
  • so I've to create a new screen for every category I've in the drawer? I'm asking because i've to display the post (obtained from fetching Json file filter by category) in a standard/common way for all the categories. There's a way for change the id of the page or something like this? – Andrea Favero Jul 31 '19 at 13:33
  • 1
    Yes you can also send the id as a parameter: `onPress={this.navigateToScreen('CategoryPage'), { id: x.id }}` – remeus Jul 31 '19 at 13:38
  • yep thanks :D. but can I route every item to the same page and reload the page like is a new one with new param? like press on "DAKAR" and i get all the post in DAKAR category (i've achieved it)... and then clicking on ECT, "reload" the same page but whit the ECT category posts? – Andrea Favero Jul 31 '19 at 14:14
  • 1
    You could check for a change in ID in `componentDidUpdate` and reload the data with the new ID. – remeus Jul 31 '19 at 14:50
  • how can I do that? – Andrea Favero Jul 31 '19 at 15:02
  • 1
    You just compare the IDs in `componentDidUpdate`. `componentDidUpdate(prevProps) { const newID = this.props.navigation.getParam('id', 0); const prevID = prevProps.navigation.getParam('id', 0); if (newID !== prevID) { console.log('ID has changed'); } }` – remeus Jul 31 '19 at 15:11