我需要将数据从我的主屏幕传递到我的第二屏幕。如果我单击主屏幕上的按钮导航到第二屏幕,则有很多示例可以做到这一点,但是如果我使用 v2 底部选项卡导航器从主屏幕转到第二屏幕,则找不到任何显示如何传递到第二屏幕的内容。我尝试了屏幕道具和其他几种方法,花了大约 8 个小时试图弄清楚,但无法让它工作。知道怎么做吗?拜托,任何提示都会很棒。 这是我的代码:
MainTabNavigator.js:
const config = Platform.select({
web: { headerMode: 'screen' },
default: {},
});
const HomeStack = createStackNavigator(
{
Home: HomeScreen,
},
config
);
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<MaterialIcons name="home" size={32} />
),
};
HomeStack.path = '';
const SecondStack= createStackNavigator(
{
Second: SecondScreen,
},
config
);
SecondStack.navigationOptions = {
tabBarLabel: 'Second screen stuff',
tabBarIcon: ({ focused }) => (
<MaterialIcons name="SecondScreenIcon" size={32} />
),
};
SecondStack.path = '';
const tabNavigator = createBottomTabNavigator({
HomeStack,
SecondScreen
});
tabNavigator.path = '';
export default tabNavigator;
主屏幕.js:
class HomeScreen extends Component {
constructor(props){
super(props);
}
componentDidMount(){
this.setState({DataFromHomeScreen: 'my data that Im trying to send to SecondScreen'})
}
//....
第二屏幕.js:
class SecondScreen extends Component {
constructor(props){
super(props);
}
render()
return(
<View>{this.props.DataFromHomeScreen}</View>
)
//....
请在下面找到我尝试过的事情:****
主屏幕.js:当我这样做时,它首先接收它,但随后传递空
render(){
return(
<View>
//all of my home screen jsx
<SecondScreen screenProps={{DataFromHomeScreen : 'data im trying to pass'}}/>
</View>
)
}
MaintTabNavigator.js:当我这样做时,它首先接收它,但随后传递空
值HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<MaterialIcons name="home" size={32} />
),
};
<HomeStack screenProps={{DataFromHomeScreen:'data im trying to pass'}}/>
HomeStack.path = '';
我也尝试了其他 5 种方法,我现在什至不记得了。我不想在第二个屏幕中再次调用我的数据库来获取用户信息。我认识的人都不知道反应或本地反应。https://reactnavigation.org/docs/en/stack-navigator.html 的 React Native 文档充其量是最小的,只显示以下内容:
const SomeStack = createStackNavigator({
// config
});
<SomeStack
screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
/>
即使您转到文档中的示例并搜索"屏幕道具"一词,您也不会在任何一个示例中看到任何提及屏幕道具功能的内容。我看到的所有问题都只涉及如何在按钮单击时传递道具,这很容易。我正在尝试做的事情可能吗?我确定我不是唯一一个使用选项卡导航器的人,他在主屏幕中检索数据并需要将其传递给其他屏幕。任何建议都会有所帮助。谢谢。
附言。 这是我正在呼叫主屏幕的登录类:
class SignInScreen extends React.Component {
static navigationOptions = {
title: 'Please sign in',
};
render() {
return (
<View
style={styles.container}
contentContainerStyle={styles.contentContainer}>
<View>
<SocialIcon
title='Continue With Facebook'
button
type='facebook'
iconSize="36"
onPress={this._signInAsync}
/>
</View>
);
}
_signInAsync = async () => {
let redirectUrl = AuthSession.getRedirectUrl();
let result = await AuthSession.startAsync({
authUrl:
`https://www.facebook.com/v2.8/dialog/oauth?response_type=token` +
`&client_id=${FB_APP_ID}` +
`&redirect_uri=${encodeURIComponent(redirectUrl)}`,
});
var token = result.params.access_token
await AsyncStorage.setItem('userToken', token);
await fetch(`https://graph.facebook.com/me?fields=email,name&access_token=${token}`).then((response) => response.json()).then((json) => {
this.props.navigation.navigate('Home',
{
UserName : json.name,
FBID : json.id,
email : json.email
});
}) .catch(() => {
console.log('ERROR GETTING DATA FROM FACEBOOK')
});
};
}
export default SignInScreen;
我认为您正在主屏幕组件的 componentDidMount 中调用您的数据库,(我是对的?)并且由于同一层次结构中的另一个组件需要相同的数据,您应该考虑将其包装到一个新组件中并在该父组件中调用您的数据,然后将数据传递给所有需要它的子组件。这是做事的反应方式。HomeScreen 的状态不应该有数据,您的数据应该位于更高层次结构的父组件中,并将数据作为 props 传递给子组件。
这样,当您创建选项卡时,您可以按照 react 本机文档的建议传递 props:
import { createBottomTabNavigator, BottomTabBar } from 'react-navigation-tabs';
const TabBarComponent = (props) => (<BottomTabBar {...props} />);
const TabScreens = createBottomTabNavigator(
{
tabBarComponent: props =>
<TabBarComponent
{...props}
style={{ borderTopColor: '#605F60' }}
/>,
},
);
另一种解决方案可能是将全局状态管理与 Redux 或类似的东西一起使用。
我希望这有所帮助。
编辑:
class Home extends React.Component{
constructor(props){
super(props);
this.state = {data: null}
}
componentDidMount() {
//get your props from navigation (your facebook credentials)
//your call to database
this.setState({data: yourResponseData});
}
render(){
const TabNavigator = createBottomTabNavigator(
{
HomeScreen: props =>
<HomeScreenStack
{...this.state.data}
/>,
SecondStack: props =>
<SecondStack
{...this.state.data}
/>,
},
);
return(
<TabNavigator />
)
}
}
const App = createAppContainer(Home);
export default App;
使用this.props.navigation.navigate
。
在HomeScreen
中,获得要发送的数据后,请导航到如下所示的SecondScreen
:
this.props.navigation.navigate('Second', { data: yourData })
要在导航到导航道具时SecondScreen
访问它,您可以将NavigationEvents
与this.props.navigation.getParam
一起使用。
/* your imports */
import { NavigationEvents } from 'react-navigation';
export default class SecondScreen extends React.Component {
/* your methods and properties */
render() {
<View>
<NavigationEvents
onDidFocus={() => this.setState({ data: this.props.navigation.getParam('data', {}) })}
/>
{ /* your SecondScreen render code */ }
</View>
}
}
编辑:例如,在您的SignInScreen
实现中,要访问道具,请使用:
const username = this.props.navigation.getParam('UserName', '')
const fbid = this.props.navigation.getParam('FBID', 0)
const email = this.props.navigation.getParam('email', '')
这是我使用的基本方法:
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const TestComponent = (props) => {
return <Text>{`TestComponent: ${props.name}`}</Text>;
};
const Home = () => {
const Tab = createBottomTabNavigator();
return (
<View style={{flex: 1}}>
<Tab.Navigator>
<Tab.Screen name="Screen 1">
{() => <TestComponent name="test 1" />}
</Tab.Screen>
<Tab.Screen name="Screen 2">
{() => <TestComponent name="test 2" />}
</Tab.Screen>
</Tab.Navigator>
</View>
);
};
请注意,要将 props 传递给Screen
,我使用的是子函数,而不是将值传递给component
。然后,子函数可以在您习惯的语法中返回您想要的组件,该组件具有可用的 props。在这种情况下,道具是简单的name
,但您可以扩展它来处理您的状态。
我最终使用了 Redux,我只花了 100 遍通读并尝试学习它,但一旦我学会了它,它就令人惊叹且简单。