这是我在 StackOverflow 上的第一篇文章,如果我没有遵循正确的格式,请道歉。
我正在使用
tab navigator from React Navigation v 5.x
构建我的第一个应用程序,并且在将道具从一个屏幕传递到另一个屏幕时遇到了一个大问题
我想要实现的是:
我尝试过this(我未能设置要传递的道具),this(已弃用的react-navigation版本)和this(也是旧版本的react-navigation)。
和 Redux,但当前版本的 React 导航没有可用的示例。
我对此已经束手无策,真的需要一步一步地了解如何实现这一目标。 这是我想做的事情的粗略草图:
我的想法是通过回调将父状态作为 props 向下发送,但我找不到在最新版本的反应导航中通过屏幕组件发送 props 的方法...
这是我的导航设置:
const Tab = createBottomTabNavigator()
export default class MyApp extends Component{
constructor(props) {
super(props);
}
render(){
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'My tests') {
iconName = focused ? 'ios-list-box' : 'ios-list';
} else if (route.name === 'Testroom') {
iconName = focused ? 'ios-body' : 'ios-body';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}>
<Tab.Screen name="My tests" component={MyTests}/> //This is where I want to send props
<Tab.Screen name="Testroom" component={TestRoom} /> //This is where I want to send props
</Tab.Navigator>
</NavigationContainer>
)
}
}
我读过this,但这对我来说毫无意义。它如何适应组件树?什么去哪儿?请帮忙!
您可以使用属性“children”来传递元素类型jsx,而不是属性“component”,这是react-native推荐的。
通过这种方式,您可以将 props 传递给组件示例:
<tab.Screen
name="home"
children={()=><ComponentName propName={propValue}/>}
/>
需要使用'()=>',因为属性children需要一个返回jsx元素的函数,它是功能性的。
查看代码注释中的答案。
<Tab.Screen
name="AdminTab"
children={() => <AdminPage userData={this.props.userSettings} />}
// component={() => <AdminPage userData={this.props.userSettings} />} <<<---- Although this will work but passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour. You can safely remove the component attribute post adding children.
/>
看起来您正在为屏幕“AdminTab”的“组件”道具传递一个内联函数(例如
})。传递内联函数将导致组件状态在重新渲染时丢失,并导致性能问题,因为它会在每次渲染时重新创建。您可以将该函数作为子函数传递给“Screen”,以实现所需的行为。component={() => <SomeComponent />
反应导航版本5+
<Tab.Screen name="Work" component={Works} initialParams={{ age: 45 }} />
可以使用
Works
组件上的道具进行访问。
为了将 props 发送到
<MyTests />
组件,在 <Tab.Screen />
内部:
<Tab.Screen name="My tests">
{() => <MyTests myPropsName={myPropsValue} />}
</Tab.Screen>
<Tab.Navigator>
<Tab.Screen name="Lead">
{() => <LeadList {...this.props} />}
</Tab.Screen>
<Tab.Screen name="Opportunity">
{() => <OpportunityList {...this.props} />}
</Tab.Screen>
</Tab.Navigator>
我还需要将一个函数传递到屏幕,以便在所有屏幕上渲染弹出窗口,但需要在特定屏幕上显示弹出窗口。这是我的解决方案。现在忘记重新渲染(性能)问题。
<Tab.Screen
initialParams={{
onRemovePress: () => {
props.setShowPopup(true)
}
}}
name="Followers"
component={Followers}
options={{
tabBarLabel: ({ focused, color }) => {
return (
<Text style={{ color: focused ? light.tintColor : light.black, marginBottom: 10 }}>{`${props.numOfFollowers} Followers`}</Text>
)
}
}}
/>
您可以使用以下
<Tab.Screen name="Favourite" component={() => <RecipeList CategoryId={0}></RecipeList>}/>
您可能会因重新渲染组件而发出当前状态丢失的警告。但道具会起作用。 如果你想复制当前状态道具,那么你可以使用 {...props}
<Tab.Screen
name='tabName'
children={()=>{
return(
<CustomComponent prop={yourProp} />
)
}}
/>
今天第一次研究这个,发现它非常有帮助,只是想提供一些小更新,对于@react-navigation/bottom-tabs,v^5.11.10,您需要确保不再传递组件Tab.screen 中的 prop 并确保 Children 中的匿名函数返回一个元素/组件。
如果您使用 ScreenMap 来渲染屏幕,您可以这样做:
_renderScene = SceneMap({
first: () => <MyEvents {...this.props} date={this.state.date} />,
second: () => <F4FEvents {...this.props} date={this.state.date} />,
});
如果您从一个选项卡导航到另一个选项卡并且未更新,请尝试此方法,这会对您有所帮助
<Tab.Screen
name="Transaction"
children={() => <GoldTransaction data={true} />}/>
这在 JS 中有效,但在 TS 中无效。
因为 TS 期望类型来自属性“children”,该属性在此处声明为类型
孩子们:(道具:{
路线:RouteProp
export declare type ScreenListeners<State extends NavigationState, EventMap extends EventMapBase> = Partial<{
[EventName in keyof (EventMap & EventMapCore<State>)]: EventListenerCallback<EventMap, EventName>;
}>;
declare type ScreenComponentType<ParamList extends ParamListBase, RouteName extends keyof ParamList> = React.ComponentType<{
route: RouteProp<ParamList, RouteName>;
navigation: any;
}> | React.ComponentType<{}>;
export declare type RouteConfigComponent<ParamList extends ParamListBase, RouteName extends keyof ParamList> = {
/**
* React component to render for this screen.
*/
component: ScreenComponentType<ParamList, RouteName>;
getComponent?: never;
children?: never;
} | {
/**
* Lazily get a React component to render for this screen.
*/
getComponent: () => ScreenComponentType<ParamList, RouteName>;
component?: never;
children?: never;
} | {
/**
* Render callback to render content of this screen.
*/
children: (props: {
route: RouteProp<ParamList, RouteName>;
navigation: any;›
}) => React.ReactNode;
component?: never;
getComponent?: never;
您可以使用参数来完成此操作。要设置初始参数或道具,您可以使用
initialParams
,如下所示:
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
initialParams={
name: 'Your name'
}
}}
/>
然后你可以使用 prop
route
访问参数,如下所示:
const HomeScreen = ({ route }) => (
<View>
<Text>Welcome to my app, {route.params.name}</Text>
</View>
)
或使用
useRoute
钩子:
const HomeScreen = () => {
const { params } = useRoute()
return (
<View>
<Text>Welcome to my app, {params.name}</Text>
</View>
)
}
更新: 您还可以使用道具
通过调用navigation
来访问参数,如下所示:navigation.getParam()
const HomeScreen = ({ navigation }) => ( <View> <Text>Welcome to my app, {navigation.getParam('name', 'Anonymous')}</Text> </View> )
采用两个参数,参数名称和默认值。您可以使用navigation.getParam()
钩子执行相同的操作。useNavigation
当您从另一个屏幕导航时,您甚至可以通过将 传递给
navigation.navigate
的第二个参数来传递参数:
const LoginScreen = ({ navigation }) => {
const [name, setName] = useState('')
return (
<View>
<TextInput
placeholder="Type your name here"
value={name}
onChangeText={(text) => setName(text)}
/>
<Button
title="Submit"
onPress={() => navigation.navigate('Home', {
/* Pass your params here */
name
})}
/>
</View>
)
}
您还可以使用
HomeScreen
更改 navigation.setParams
组件中的参数并传入新参数:
const HomeScreen = ({ route, navigation }) => (
<View>
<Text>Welcome to my app, {route.params.name}</Text>
<Button
title="Reset name"
onPress={() => navigation.setParams({
name: ''
})}
/>
</View>
)
注意: 如果组件是导航器中使用的页面,则只能访问
和route
属性。navigation
有关传递参数的更多信息,请访问 https://reactnavigation.org/docs/params
虽然这是更流行的方法,但还有其他方法可以完成此任务,例如传递
children
的 Tab.Screen
属性作为内联组件,或者将屏幕数据置于应用程序状态。您可以选择要采用的方法,但 React 导航参数可能是您的最佳选择。