[英]React Native: How to prevent state reset when changing screens?
I am having trouble when changing screens after the user access a card.用户访问卡片后更改屏幕时遇到问题。 The component set of states resets whenever the client accesses a card, changes the screen, and returns to the same component before.
每当客户端访问卡片、更改屏幕并返回到之前的相同组件时,组件状态集都会重置。
Here is how the app works.这是该应用程序的工作方式。 The client access a list of quotes (QuotesRequestedListScreen) that they requested.
客户端访问他们请求的报价列表 (QuotesRequestedListScreen)。 This said list is loaded from Firebase, and thus the state to indicate loading activity is set to true at first.
该列表是从 Firebase 加载的,因此首先将指示加载活动的 state 设置为 true。 After the load finishes, then the app shows all the data in cards.
加载完成后,应用程序会在卡片中显示所有数据。 After the client clicks on the card, it changes the screen and displays the card info.
客户端点击卡片后,画面切换,显示卡片信息。 However, if the client returns to the previous screen, the screen shows the loading activity icon forever until changing screens again.
但是,如果客户端返回到前一个屏幕,该屏幕将永远显示加载活动图标,直到再次切换屏幕。
I have tried to use State Persistance given by React Navigation , but it did not work when I was trying to return to the quote list screen (QuotesRequestedListScreen).我尝试使用由 React Navigation 提供的 State 持久性,但是当我尝试返回报价列表屏幕(QuotesRequestedListScreen)时它不起作用。
Does someone know what is the best way to keep the states when changing screens?有人知道在更改屏幕时保持状态的最佳方法是什么? Thanks!
谢谢!
Main Quote Screen主报价屏幕
const QuoteScreen = (props) => {
const QuotesRequestedScreen = () => {
return (
<Stack.Navigator headerMode="none" initialRouteName="Quote List">
<Stack.Screen name="Quote List" component={QuotesRequestedListScreen} />
<Stack.Screen name="Card" component={QuoteRequestedCardScreen} />
</Stack.Navigator>
);
};
return (
<Tab.Navigator initialRouteName="Request Quote">
<Tab.Screen name="Request Quote" component={RequestQuoteScreen} />
<Tab.Screen name="Quotes Requested" component={QuotesRequestedScreen} />
</Tab.Navigator>
);
};
export default QuoteScreen;
QuotesRequestedListScreen报价请求列表屏幕
const QuotesRequestedListScreen = (props) => {
//Getting userID for the useEffect
let userId = useSelector((state) => state.user.userId);
const {height} = Dimensions.get('window');
//
////USESTATES
//
const [quoteStatusCards, setQuoteStatusCards] = useState([]);
const [airportList, setAirportList] = useState([]);
const [rawQuotes, setRawQuotes] = useState([]);
const [errorDetector, setErrorDetector] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [isUserLogged, setIsUserLogged] = useState(true);
//
////USEEFFECTS
//
useEffect(() => {
//Function that starts the verification once it has the focus
const unsubscribe = props.navigation.addListener('focus', () => {
if (userId !== null) {
console.log('Entrei aqui');
getQuotes();
} else {
setIsLoading(false);
setIsUserLogged(false);
}
});
return unsubscribe;
}, [userId]);
//
//// FUNCTIONS
//
const getQuotes = async () => {
await firebase.getQuotesById(userId).then(async (results) => {
if (results.isError) {
errorOperationQuote(results.errorMessage);
} else {
//Then it tries to get the airportlist from asyncStorage.
await AsyncStorage.getItem('airportList')
.then(async (list) => {
//Checks if the list is empty
if (list != null) {
//If it's not, then it checks the last version in the database with the one stored in the asyncstorage
await firebase.compareAirportListVersion().then((result) => {
if (result.isError) {
//If there are errors, then it reports the error to the user
errorOperationQuote(result.errorMessage);
} else {
if (result.success) {
//If it's the same version, then it loads inside airportList;
setAirportList(JSON.parse(list));
setRawQuotes(results.quotes);
setIsLoading(false);
} else {
//If it's not the same version, then it downloads the whole list again.
downloadAirportList(results.quotes);
}
}
});
} else {
//If the list's empty, then it downloads the airport
downloadAirportList(results.quotes);
}
})
.catch((error) => {
errorOperationQuote(error.errorMessage);
});
}
});
};
//Downloads the airport list and set it to the AirportList state.
const downloadAirportList = async (quotes) => {
await firebase.getAirports().then((result) => {
if (result.success) {
setAirportList(JSON.parse(result.airportList));
setRawQuotes(quotes);
} else {
errorOperationQuote(result.errorMessage);
}
});
};
//
////RETURN
//
return (
<Container>
<Content contentContainerStyle={styles.quoteCardsContainer}>
{isLoading ? (
<View style={styles.loadingErrorContainers}>
<Spinner style={{alignItems: 'center'}} color={colors.colorRed} />
</View>
) : !isUserLogged ? (
<View style={styles.loadingErrorContainers}>
<Text style={styles.errorMessageText}>
User is not logged in. Please, log in first before checking the
quotes requested.
</Text>
<Button
onPress={() => {
props.navigation.navigate('Login');
}}>
Login
</Button>
</View>
)
///...
</Content>
</Container>
);
}
QuoteRequestedCardScreen报价请求卡屏幕
const QuoteRequestedCardScreen = (props) => {
const [quoteInfo, setQuoteInfo] = useState(props.route.params?.selectedQuote);
console.log(quoteInfo);
return (
<Container>
<Content style={{marginHorizontal: 10}}>
<Card>
<CardItem style={{paddingLeft: 0}} header>
<View style={{flexDirection: 'row'}}>
<Button
onPress={() => props.navigation.navigate('Quote List')}
transparent>
<Icon name="arrow-left" type="FontAwesome5" />
</Button>
//...
</View>
</CardItem>
</Card>
</Content>
</Container>
);
};
export default QuoteRequestedCardScreen;
The problem is that you're creating a component inside another component.问题是您正在另一个组件中创建一个组件。 Your function component
QuotesRequestedScreen
is defined inside the QuoteScreen
function.您的 function 组件
QuotesRequestedScreen
在QuoteScreen
function 中定义。
You should NEVER define components inside other components or your state will be lost on re-render due to remount.您永远不应该在其他组件中定义组件,否则您的 state 将由于重新安装而在重新渲染时丢失。 Just move the
QuotesRequestedScreen
to outside the QuoteScreen
function and then it'll work as expected.只需将
QuotesRequestedScreen
移到QuoteScreen
function 之外,它就会按预期工作。
More information from React Navigation docs https://reactnavigation.org/docs/troubleshooting#screens-are-unmountingremounting-during-navigation更多信息来自 React Navigation 文档https://reactnavigation.org/docs/troubleshooting#screens-are-unmountingremounting-during-navigation
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.