如何在 React Native 中清理 class 组件中的状态?
How to clean up state in class component in React Native?
我是 React Native 的新手,正在努力清理屏幕状态。
比如屏幕 A 有一些状态 --> 屏幕 B,回到屏幕 A,旧状态很清楚。我正在使用 React Navigation V5
我想做的是:
- 从
MainMap.js
导航到最后一屏TripsListScreen.js
后(整个过程是一个Stack of 4 screens,嵌套在一个Drawer中),我得到了所有存储在Redux的store中的数据,并且在 TripsListScreen
. 中显示
- 问题是当我在
TripsListScreen
按下 add
按钮在 MainMap.js
返回时,它并没有像我预期的那样清理每个状态。
这是 MainMap.js
的状态:
const initialState = {
hasMapPermission: false,
_userLocationDisplayed: null,
userLatitude: 0,
userLongitude: 0,
initial_UserLatitude: 0,
initial_UserLongitude: 0,
userLocationAddress: '',
destination: [],
destinationName: [],
destinationAddress: [],
destinationCoords: [],
destinationImageUri: [],
numOfInput:[0,1],
counter: 1,
wayPoints: [],
markers: [],
}
class MainMap extends React.Component{
constructor(props){
super(props);
this.state = initialState;
};
componentDidMount(){
console.log('Hello',this.props)
if(this.props.route.params === true){
this.setState(initialState)
}
this._requestUserLocation();
};
基本上,我尝试将布尔参数从 TripsListScreen
传递到 MainMap
,如果参数为真,我会将所有状态设置回开头。但是,它没有按预期工作。
这里是TripsListScreen
:
//...
<Layout style={styles.bottom}>
<TouchableOpacity onPress={() => props.navigation.navigate('PlanningProcess', {
screen: 'MainMapScreen',
params: {doAddPlace: true}
})} style={styles.createTrip}>
<Layout style={styles.button} >
<Icon name='add' size={35} />
</Layout>
</TouchableOpacity>
</Layout>
//...
这是导航:
StackNavigators
:
const Stack = createStackNavigator();
const StackNavigator = (props) => {
return(
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name='MainMapScreen' component={MainMap} />
<Stack.Screen name='TripDescription' component={TripDescription} />
<Stack.Screen name='TripsListDetailScreen' component={TripsListDetailScreen} />
<Stack.Screen
name='TripsListScreen'
component={TripsListScreen}
options={{
headerLeft: () => (<Icon style={{marginHorizontal: 30, marginTop: 30}} color='white' name='menu' size={30} onPress={() => props.navigation.dispatch(DrawerActions.openDrawer())}/>),
title:'Something'
}}
/>
</Stack.Navigator>
);
};
export default StackNavigator;
- 主要
Navigators
:
const Navigator = () => {
return(
<NavigationContainer>
<Drawer.Navigator
statusBarAnimation='slide'
drawerContent={props =>
<DrawerContent {...props} />}>
<Drawer.Screen name='Welcome' component={WelcomeStackScreen} />
<Drawer.Screen name='TripsListScreen' component={TripsListScreen} />
<Drawer.Screen name='PlanningProcess' component={StackNavigators} />
</Drawer.Navigator>
</NavigationContainer>
);
};
export default Navigator;
这是 MainMap
呈现的内容:
这是我预期的,当从 TripsListScreen
导航时(创建新行程):
请帮忙!!!
在 StackNavigator 中,当您在屏幕顶部打开新屏幕时,屏幕不会卸载。因此,如果您从 A 转到 B,然后从 B 转到 C,A 和 B 都将保持挂载状态。如果您从 C 返回到 B,C 将卸载。这就像数组上的 push
和 pop
方法。当您返回 MainMap 时,componentDidMount
不会被调用,因为它不会首先卸载。这里解释一下Navigation Lifecycle。
当您使用 Redux 并说所有数据都存储在 Redux 存储中时,让您的 MainMap 组件仅从存储中的数据呈现,而不是从自己的状态中呈现。然后,您可以通过调度操作从 TripsListScreen 操纵这些数据。最简单的方法是创建类似 RESET_MAIN_MAP
的操作,它将重置 MainMap 屏幕
的那部分状态
MainMap.js 中的 ComponentDidMount 不会被触发,因为屏幕已经安装。请看这个
方法 ComponentDidMount()
仅在第一次安装组件时触发,当您导航到新屏幕时,前一个屏幕仍安装在堆栈中。
如果您想在每次组件获得焦点时重新初始化您的状态,您可以在导航焦点上设置一个侦听器。
像这样,
const unsubscribe = navigation.addListener('willFocus', () => {
// Do something
// re-initialise the state
});
我是 React Native 的新手,正在努力清理屏幕状态。
比如屏幕 A 有一些状态 --> 屏幕 B,回到屏幕 A,旧状态很清楚。我正在使用 React Navigation V5
我想做的是:
- 从
MainMap.js
导航到最后一屏TripsListScreen.js
后(整个过程是一个Stack of 4 screens,嵌套在一个Drawer中),我得到了所有存储在Redux的store中的数据,并且在TripsListScreen
. 中显示
- 问题是当我在
TripsListScreen
按下add
按钮在MainMap.js
返回时,它并没有像我预期的那样清理每个状态。
这是 MainMap.js
的状态:
const initialState = {
hasMapPermission: false,
_userLocationDisplayed: null,
userLatitude: 0,
userLongitude: 0,
initial_UserLatitude: 0,
initial_UserLongitude: 0,
userLocationAddress: '',
destination: [],
destinationName: [],
destinationAddress: [],
destinationCoords: [],
destinationImageUri: [],
numOfInput:[0,1],
counter: 1,
wayPoints: [],
markers: [],
}
class MainMap extends React.Component{
constructor(props){
super(props);
this.state = initialState;
};
componentDidMount(){
console.log('Hello',this.props)
if(this.props.route.params === true){
this.setState(initialState)
}
this._requestUserLocation();
};
基本上,我尝试将布尔参数从 TripsListScreen
传递到 MainMap
,如果参数为真,我会将所有状态设置回开头。但是,它没有按预期工作。
这里是TripsListScreen
:
//...
<Layout style={styles.bottom}>
<TouchableOpacity onPress={() => props.navigation.navigate('PlanningProcess', {
screen: 'MainMapScreen',
params: {doAddPlace: true}
})} style={styles.createTrip}>
<Layout style={styles.button} >
<Icon name='add' size={35} />
</Layout>
</TouchableOpacity>
</Layout>
//...
这是导航:
StackNavigators
:
const Stack = createStackNavigator();
const StackNavigator = (props) => {
return(
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name='MainMapScreen' component={MainMap} />
<Stack.Screen name='TripDescription' component={TripDescription} />
<Stack.Screen name='TripsListDetailScreen' component={TripsListDetailScreen} />
<Stack.Screen
name='TripsListScreen'
component={TripsListScreen}
options={{
headerLeft: () => (<Icon style={{marginHorizontal: 30, marginTop: 30}} color='white' name='menu' size={30} onPress={() => props.navigation.dispatch(DrawerActions.openDrawer())}/>),
title:'Something'
}}
/>
</Stack.Navigator>
);
};
export default StackNavigator;
- 主要
Navigators
:
const Navigator = () => {
return(
<NavigationContainer>
<Drawer.Navigator
statusBarAnimation='slide'
drawerContent={props =>
<DrawerContent {...props} />}>
<Drawer.Screen name='Welcome' component={WelcomeStackScreen} />
<Drawer.Screen name='TripsListScreen' component={TripsListScreen} />
<Drawer.Screen name='PlanningProcess' component={StackNavigators} />
</Drawer.Navigator>
</NavigationContainer>
);
};
export default Navigator;
这是 MainMap
呈现的内容:
这是我预期的,当从 TripsListScreen
导航时(创建新行程):
请帮忙!!!
在 StackNavigator 中,当您在屏幕顶部打开新屏幕时,屏幕不会卸载。因此,如果您从 A 转到 B,然后从 B 转到 C,A 和 B 都将保持挂载状态。如果您从 C 返回到 B,C 将卸载。这就像数组上的 push
和 pop
方法。当您返回 MainMap 时,componentDidMount
不会被调用,因为它不会首先卸载。这里解释一下Navigation Lifecycle。
当您使用 Redux 并说所有数据都存储在 Redux 存储中时,让您的 MainMap 组件仅从存储中的数据呈现,而不是从自己的状态中呈现。然后,您可以通过调度操作从 TripsListScreen 操纵这些数据。最简单的方法是创建类似 RESET_MAIN_MAP
的操作,它将重置 MainMap 屏幕
MainMap.js 中的 ComponentDidMount 不会被触发,因为屏幕已经安装。请看这个
方法 ComponentDidMount()
仅在第一次安装组件时触发,当您导航到新屏幕时,前一个屏幕仍安装在堆栈中。
如果您想在每次组件获得焦点时重新初始化您的状态,您可以在导航焦点上设置一个侦听器。
像这样,
const unsubscribe = navigation.addListener('willFocus', () => {
// Do something
// re-initialise the state
});