如何使用react-native的嵌套路由

时间:2016-03-22 14:17:29

标签: reactjs react-native reactjs-flux

我正在使用react-native-router-flux为我的应用程序主导航。我需要设置一个嵌套路由器。我有一个地图组件,其侧栏有一个区域列表。当我单击一行时,我需要切换到具有属于该区域的细分列表的视图。我看了一些例子并试图弄明白。目前在控制台中没有错误,但侧边栏中没有显示任何内容。如果有更好的方法,请告诉我。谢谢!

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;

领土

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;

细分

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;

1 个答案:

答案 0 :(得分:5)

右。

最好的方法是在组件的道具中使用导航器 - 所以,在这种情况下,如果你有一个ListView组件,你想要移动到一个DetailedView组件,只需调用navigator.push(应该通过props传递给ListView)。

换句话说,你将Navigator传递给ListView,可以在this.props.navigator上找到。然后(在onPress内),只需在导航器上调用push,然后输入您要渲染的下一个组件(以及您希望拥有的任何其他道具) 。

在这种情况下,我希望您的代码看起来像这样:

// 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
});

希望这有帮助!