解除状态以便我可以使用 onPress 修改它
Lifting a state so I can modify it with an onPress
我想弄清楚提升状态是如何工作的。目前,我正在尝试在不同的组件中使用 onPress 来更改状态。在我下面提供的小吃演示中,ListHome
和 MapHome
出于某种原因没有响应,但您仍然会看到我正在努力完成的事情。
我想要地图和列表“按钮”来完成“单击此按钮”的功能。
Demo - 当前的实现没有错误,除了可触摸不透明的闪光之外没有其他响应。 (还记得零食因为某些原因没有响应。我的本地设备工作正常)
编辑:明确地说,我希望能够从另一个组件访问和更改状态 whichComponentToShow
。即 ListHome
组件。
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
whichComponentToShow: 'Screen1',
};
}
goToMap = () => {
this.setState({ whichComponentToShow: 'Screen2' });
};
render(){
if(this.state.whichComponentToShow === 'Screen1'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<ListHome
renderMap = {this.goToMap.bind(this)}
/>
}
}
export default class ListHome extends React.Component {
goToMap = () => {
this.props.renderMap();
}
<TouchableOpacity onPress={() => this.goToMap.bind(this)}>
<View style={styles.conditionalMap}>
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: 'black', fontSize: scale(15)}}>
Map
</Text>
</View>
</View>
</TouchableOpacity>
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import VenueDetailsScreen from './screens/VenueDetails';
import CarouselGallary from './screens/Carousel';
import Home from './screens/Home';
import Friends from './screens/Friends';
import Profile from './screens/Profile';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={Home}
options={{ headerShown: false }}
/>
<Stack.Screen
name="VenueDetails"
component={VenueDetailsScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="CarouselGallary"
component={CarouselGallary}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Friends"
component={Friends}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Profile"
component={Profile}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarActiveTintColor: '#F60081',
tabBarInactiveTintColor: '#4d4d4d',
tabBarStyle: {
backgroundColor: '#d1cfcf',
borderTopColor: 'transparent',
},
}}>
<Tab.Screen
name="Home"
component={MyTabs}
options={{
tabBarLabel: 'Home',
headerShown: false,
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Friends"
component={Friends}
options={{
tabBarLabel: 'Friends',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account-group"
color={color}
size={size}
/>
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account"
color={color}
size={size}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
const Stack = createStackNavigator();
您要实现的是一个常见用例,即更新祖先组件中的状态。您基本上有一个如下所示的组件树:
您正在尝试使用设置主屏幕状态的 renderMap
属性从 ListHome
组件更新 Home
组件的状态。这是有道理的,所以你已经掌握了基本原理,它不起作用的原因是ListHome
组件
中的一个小错误
<View style={styles.conditionalMap}>
<TouchableOpacity onPress={() => this.goToMap.bind(this)}>
// In the above line, change to this.goToMap()
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'black', fontSize: scale(15) }}>Map</Text>
</View>
</TouchableOpacity>
</View>
这就是 bind 方法的作用:
The bind() method creates a new function that, when called, has this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
所以onPress
目前定义的方式,它会创建一个新的函数,但是这个函数从来没有真正被调用过。将 this.goToMap.bind(this)
更改为 this.goToMap()
应该可以解决您的问题。
我想弄清楚提升状态是如何工作的。目前,我正在尝试在不同的组件中使用 onPress 来更改状态。在我下面提供的小吃演示中,ListHome
和 MapHome
出于某种原因没有响应,但您仍然会看到我正在努力完成的事情。
我想要地图和列表“按钮”来完成“单击此按钮”的功能。
Demo - 当前的实现没有错误,除了可触摸不透明的闪光之外没有其他响应。 (还记得零食因为某些原因没有响应。我的本地设备工作正常)
编辑:明确地说,我希望能够从另一个组件访问和更改状态 whichComponentToShow
。即 ListHome
组件。
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
whichComponentToShow: 'Screen1',
};
}
goToMap = () => {
this.setState({ whichComponentToShow: 'Screen2' });
};
render(){
if(this.state.whichComponentToShow === 'Screen1'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<ListHome
renderMap = {this.goToMap.bind(this)}
/>
}
}
export default class ListHome extends React.Component {
goToMap = () => {
this.props.renderMap();
}
<TouchableOpacity onPress={() => this.goToMap.bind(this)}>
<View style={styles.conditionalMap}>
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: 'black', fontSize: scale(15)}}>
Map
</Text>
</View>
</View>
</TouchableOpacity>
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import VenueDetailsScreen from './screens/VenueDetails';
import CarouselGallary from './screens/Carousel';
import Home from './screens/Home';
import Friends from './screens/Friends';
import Profile from './screens/Profile';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={Home}
options={{ headerShown: false }}
/>
<Stack.Screen
name="VenueDetails"
component={VenueDetailsScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="CarouselGallary"
component={CarouselGallary}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Friends"
component={Friends}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Profile"
component={Profile}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarActiveTintColor: '#F60081',
tabBarInactiveTintColor: '#4d4d4d',
tabBarStyle: {
backgroundColor: '#d1cfcf',
borderTopColor: 'transparent',
},
}}>
<Tab.Screen
name="Home"
component={MyTabs}
options={{
tabBarLabel: 'Home',
headerShown: false,
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Friends"
component={Friends}
options={{
tabBarLabel: 'Friends',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account-group"
color={color}
size={size}
/>
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account"
color={color}
size={size}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
const Stack = createStackNavigator();
您要实现的是一个常见用例,即更新祖先组件中的状态。您基本上有一个如下所示的组件树:
您正在尝试使用设置主屏幕状态的 renderMap
属性从 ListHome
组件更新 Home
组件的状态。这是有道理的,所以你已经掌握了基本原理,它不起作用的原因是ListHome
组件
<View style={styles.conditionalMap}>
<TouchableOpacity onPress={() => this.goToMap.bind(this)}>
// In the above line, change to this.goToMap()
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'black', fontSize: scale(15) }}>Map</Text>
</View>
</TouchableOpacity>
</View>
这就是 bind 方法的作用:
The bind() method creates a new function that, when called, has this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
所以onPress
目前定义的方式,它会创建一个新的函数,但是这个函数从来没有真正被调用过。将 this.goToMap.bind(this)
更改为 this.goToMap()
应该可以解决您的问题。