初始ReactNative中的路由
基础页面跳转
路由跳转(navigation)
function DetailsScreen({ navigation }) {return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Text>Details Screen</Text><Buttontitle="Go to Details... again"onPress={() => navigation.navigate('Details')}/></View>);}
路由跳转(push)
<Buttontitle="Go to Details... again"onPress={() => navigation.push('Details')}/>
注意
navigation和push的区别 Each time you call push we add a new route to the navigation stack. When you call navigate it first tries to find an existing route with that name, and only pushes a new route if there isn’t yet one on the stack.
路由回退(goBack)
function DetailsScreen({ navigation }) {return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Text>Details Screen</Text><Buttontitle="Go to Details... again"onPress={() => navigation.push('Details')}/><Button title="Go to Home" onPress={() => navigation.navigate('Home')} /><Button title="Go back" onPress={() => navigation.goBack()} /></View>);}
回退多屏(popToTop)
popToTop是直接返回当前页面展栈中的最顶层 如果想要回退到指定的页面,需要使用navigate
function DetailsScreen({ navigation }) {return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Text>Details Screen</Text><Buttontitle="Go to Details... again"onPress={() => navigation.push('Details')}/><Button title="Go to Home" onPress={() => navigation.navigate('Home')} /><Button title="Go back" onPress={() => navigation.goBack()} /><Buttontitle="Go back to first screen in stack"onPress={() => navigation.popToTop()}/></View>);}
- navigation.navigate(‘RouteName’) 推送一个新的路由到本地堆栈导航器,如果它还没有在堆栈中,否则它会跳到该屏幕。
- 我们可以随意调用navigation.push(‘RouteName’),它将继续推送路由。
- 标题栏会自动显示一个返回按钮,但你可以通过调用navigation.goBack()以编程方式返回。在Android上,硬件的返回按钮就像预期的那样。
- 你可以通过navigation.navigate(‘RouteName’)回到堆栈中的一个现有屏幕,你也可以通过navigation.popToTop()回到堆栈中的第一个屏幕。
- 导航道具对所有屏幕组件(在路由配置中定义为屏幕并被React Navigation渲染为路由的组件)都可用。
页面传参
假定参数为
params, 那么一般通过navigation.navigate(path, params)来在页面跳转的时候传递参数
function HomeScreen({ navigation }) {return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Text>Home Screen</Text><Buttontitle="Go to Details"onPress={() => {/* 1. Navigate to the Details route with params */navigation.navigate('Details', {itemId: 86,otherParam: 'anything you want here',});}}/></View>);}function DetailsScreen({ route, navigation }) {/* 2. Get the param */const { itemId, otherParam } = route.params;return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Text>Details Screen</Text><Text>itemId: {JSON.stringify(itemId)}</Text><Text>otherParam: {JSON.stringify(otherParam)}</Text><Buttontitle="Go to Details... again"onPress={() =>navigation.push('Details', {itemId: Math.floor(Math.random() * 100),})}/><Button title="Go to Home" onPress={() => navigation.navigate('Home')} /><Button title="Go back" onPress={() => navigation.goBack()} /></View>);}
在
props中可以结构出route对象,route对象包含了当前页面的一些信息,比如name,param等等在
params中我们可以拿到传递的参数
在界面中,我们对传递过来的参数进行更新,就像更新自身的状态一样:
navigation.setParams({query: 'someText',});
也可以在路由配置中给界面添加默认的参数,如下所示:
<Stack.Screenname="Details"component={DetailsScreen}initialParams={{ itemId: 42 }}/>
- 如果导航到某个界面时没有指定任何的参数,那么就会使用默认的参数
- 默认参数也会和传递的参数进行浅层次合并
除了可以从其他界面接收参数以外,我们还可以向之前的界面传递参数。比如我们在首页点击登录,一般会跳转到另外一个专门的页面进行信息的填写,而当我们登录完毕后,可以将登陆成功的信息返回给首页。
这一般使用的是navigation.navigate()
function HomeScreen({ navigation, route }) {React.useEffect(() => {if (route.params?.post) {// Post updated, do something with `route.params.post`// For example, send the post to the server}}, [route.params?.post]);return (<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Buttontitle="Create post"onPress={() => navigation.navigate('CreatePost')}/><Text style={{ margin: 10 }}>Post: {route.params?.post}</Text></View>);}function CreatePostScreen({ navigation, route }) {const [postText, setPostText] = React.useState('');return (<><TextInputmultilineplaceholder="What's on your mind?"style={{ height: 200, padding: 10, backgroundColor: 'white' }}value={postText}onChangeText={setPostText}/><Buttontitle="Done"onPress={() => {// Pass and merge params back to home screennavigation.navigate({name: 'Home',params: { post: postText },merge: true,});}}/></>);}
在路由传递参数的过程中,我们需要有一种传递参数的规范,哪些数据可以放在路由参数中,而哪些不建议放在里面。
简单来讲,我们只需要传递最核心、最重要的那个数据,这个数据的地位可以类比成数据库中的主键那样,可以唯一确定一条数据。比如,我们需要传递的应该是用户id而不是用户的全部信息,用户的全部信息应该放在一种全局存储中。
比如我们现在需要跳转到用户个人资料界面,很多人可能直接传递下面这种参数:
// Don't do thisnavigation.navigate('Profile', {user: {id: 'jane',firstName: 'Jane',lastName: 'Done',age: 25,},});
但事实上,并不推荐这么做,这可能导致在界面上显示的是过时的数据,正确的做法应该是只传入用户的编号,而具体数据通过后续查询来得到:
navigation.navigate('Profile', { userId: 'jane' });
- navigate和push接受一个可选的第二个参数,让你向你正在导航的路由传递参数。例如navigation.navigate(‘RouteName’, { paramName: ‘value’ }) 。
- 你可以在一个屏幕内通过route.params读取参数
- 你可以通过 navigation.setParams 来更新屏幕的参数
- 初始参数可以通过屏幕上的initialParams来进行传递。
- 参数应该包含显示屏幕所需的最小数据,而不是更多
在