Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use nested routing with react-native

I am using react-native-router-flux for my apps main navigation. I need to setup a nested router. I have a map component that has a side bar with a List of Territories. When I click on a row I need to switch to a view that has the List of Subdivisions that belong to that Territory. I looked at some examples and tried to figure it out. Currently there are no errors in console but nothing shows up in the sidebar. If there is a better way of doing this please let me know. thanks!

Maprouter

    export default class RootRouter extends Component {
    render() {
        return(
            <Router hideNavBar={true}>
                <Schema name="default" sceneConfig={Navigator.SceneConfigs.FloatFromRight}/>
                <Route name="mapSurveyTerritories" wrapRouter={false} component={MapSurveyTerritories} initial={true}/>
                <Route name="mapSubdivisions" wrapRouter={false} component={MapSubdivisions} />
            </Router>
        );
    }
}

Map Component

BackAndroid.addEventListener('hardwareBackPress', function() {
    Actions.pop();
    return true;
});
export default class Map extends Component {
    constructor(props) {
        super(props);
        this.state = {
            region: Albuquerque,
        };
    }


    render() {
        const { region, markers,surveyTerritories,selectedMarket } = this.state;
        return (
          <View style={styles.container}>
                    <Navbar
                        title="Map"/>

            <View style={styles.innerContainer}>
                <MapView
                    style={styles.map}
                    initialRegion={region}
                    onLongPress={this.onPress.bind(this)}>
                    {markers.map(marker => (
                        <MapView.Marker
                            ref="m1"
                            key={marker.id}
                            coordinate={marker.coordinate}
                            title={marker.name}>
                        </MapView.Marker>
                    ))}
                </MapView>
                <ScrollView style={styles.sidebarContainer}>

                    <MapRouter />
                </ScrollView>
            </View>
          </View>
        );
    }
};

module.exports = Map;

Territories

class MapSurveyTerritories extends Component {
    constructor(props) {
        super(props);

        var ds = new ListView.DataSource({
            rowHasChanged: (r1, r2) => r1 != r2
        });

        this.state = {
            dataSource: ds,
            showProgress: true
        };
    }

    componentDidMount() {
        this.fetchTerritories();
    }

    fetchTerritories() {
        this.setState({
            dataSource: this.state.dataSource
                .cloneWithRows(territoriesAlbuquerque),
            showSpinner: false
        });
    }

    renderRow(rowData) {
        return (
            <TouchableHighlight
                onPress={()=>Actions.mapSubdivisions({selectedTerritory:rowData})}
                underlayColor='#ddd'>
                <View style={styles.row}>
                    <View style={{paddingLeft: 20}}>
                        <Text>
                            <Text style={{ fontWeight: '600' }}> {rowData.properties.name} </Text>
                        </Text>
                    </View>
                </View>
            </TouchableHighlight>
        );
    }

    render() {
        return (
            <View style={{flex: 1,justifyContent: 'flex-start'}}>
<ListView
                    dataSource={this.state.dataSource}
                    renderRow={this.renderRow.bind(this)}/>
            </View>
        );
    }
}

module.exports = MapSurveyTerritories;

Subdivisions

class MapSubdivisions extends Component {
    constructor(props) {
        super(props);
var ds = new ListView.DataSource({
            rowHasChanged: (r1, r2) => r1 != r2
        });
this.state = {
            dataSource: ds
        };
    }

    componentDidMount() {
        this.fetchSubdivisions();
    }

    fetchSubdivisions() {
        console.log('fetchSubdivisions', this.props.selectedTerritory);
        this.setState({
            dataSource: this.state.dataSource
                .cloneWithRows(subdivisionsAlbuquerque),
            showSpinner: false
        });
    }

    renderRow(rowData) {
        return (
            <TouchableHighlight
                onPress={()=>Actions.mapSubdivisionDetail({selectedSubdivision:rowData})}
                underlayColor='#ddd'>
                <View style={styles.row}>
                    <View style={{paddingLeft: 20}}>
                        <Text>
                            <Text style={{ fontWeight: '600' }}> {rowData.properties.name} </Text>
                        </Text>
                    </View>
                </View>
            </TouchableHighlight>
        );
    }

    render() {
         return (
            <View style={{flex: 1,justifyContent: 'flex-start'}}>
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={this.renderRow.bind(this)}/>
            </View>
        );
    }
}

module.exports = MapSubdivisions;
like image 517
texas697 Avatar asked Mar 22 '16 14:03

texas697


People also ask

Can we use nested routes in react?

js application to implement nested routing in the current version of react-router that is React Router DOM version 6. We use nested routing in our application so that a parent component has control over its child component at the route level.

What are nested routes react router?

In my own words, a nested route is a region within a page layout that responds to route changes. For example, in a single-page application, when navigating from one URL to another, you do not need to render the entire page, but only those regions within the page that are dependent on that URL change.

How would you render nested routes in your application?

To do this, you use React Router's Outlet component. If the app's location matches the nested Route 's path , this Outlet component will render the Route 's element .


1 Answers

Right.

The best way to go about this is to use the Navigator through the component's props- so, in this case, if you have a ListView component that you'd like to move to a DetailedView component, simply call navigator.push (which should be passed to ListView through props).

In other words, you have Navigator getting passed down to ListView, available on this.props.navigator. Then (inside an onPress), just call a push on the navigator, feeding in the next component you'd like to render (along with any other props you'd like it to have as well).

In this case, I would expect your code to look something like this:

// Within the ListView component's 'onPress' event

this.props.navigator.push({
  component: DetailedView,
  location: this.props.location,
  // any other props you need to access inside DetailedView
});

Hope this helps!

like image 80
Smee Avatar answered Oct 06 '22 01:10

Smee