React native 在渲染JSX零件之前使用效果火
我在expo react本机应用程序中有一个功能组件,如下代码所示。我遇到的问题是React native 在渲染JSX零件之前使用效果火,react-native,use-effect,React Native,Use Effect,我在expo react本机应用程序中有一个功能组件,如下代码所示。我遇到的问题是渲染部分,即JSX出现的地方,在useffect中的代码之前执行 我想在useEffect部分之后执行渲染部分,这样当useEffect执行AuthenticatedNavigator显示的另一个组件时,屏幕不会因为UnAuthenticatedNavigator先显示而闪烁,然后在大约一秒钟后闪烁 问题:如何确保渲染部分在下面的useffect部分应用程序组件之后执行 App.js const-App=()=>{
渲染部分
,即JSX出现的地方,在useffect
中的代码之前执行
我想在useEffect部分之后执行渲染部分,这样当useEffect执行AuthenticatedNavigator显示的另一个组件时,屏幕不会因为UnAuthenticatedNavigator先显示而闪烁,然后在大约一秒钟后闪烁
问题:如何确保渲染部分
在下面的useffect
部分应用程序组件之后执行
App.js
const-App=()=>{
const[user,setUser]=useState();//user是与用户相关的数据,包括userToken、companyId、email、fullName
const getUserData=async()=>{
试一试{
const userData=await AsyncStorage.getItem('@userData');
if(userData!==null){
setUser(JSON.parse(userData));
}
}捕获(e){
警报(“对不起!读取用户数据时发生意外错误。”);
}
};
const setUserData=async(userData)=>{
试一试{
如果(用户数据){
const jsonValue=JSON.stringify(userData);
等待AsyncStorage.setItem(“@userData”,jsonValue);
setUser(value);//更改状态以便重新渲染
}
}捕获(e){
警报(“抱歉!保存用户数据时发生意外错误。”);
}
}
useffect(()=>{
getUserData();//这在渲染部分之后执行。我希望它在渲染部分之前执行
}, []);
//如下所示呈现部分。由于useEffect部分在此呈现部分之后执行,因此用户最初仍然未定义。
返回(
(用户?:)
);
};
屏幕将至少呈现一次,因此您可以使用此模式使用ActivityIndicator显示加载,直到用户加载为止
const App = () => {
const [user, setUser] = useState(); //user is user related data including userToken, companyId, email, fullName
const [loading, setLoading] = useState(true);
const getUserData = async () => {
try {
const userData = await AsyncStorage.getItem('@userData');
if (userData !== null) {
setUser(JSON.parse(userData));
}
setLoading(false);
} catch (e) {
alert('Sorry! An unexpected error has occurred while reading user data.');
}
};
const setUserData = async (userData) => {
try {
if (userData) {
const jsonValue = JSON.stringify(userData);
await AsyncStorage.setItem('@userData', jsonValue);
setUser(value); //change state so re-rendering happens
}
} catch (e) {
alert('Sorry! An unexpected error has occurred while saving user data.');
}
};
useEffect(() => {
getUserData(); //this executes after the render part. I would like it to execute before the render part
}, []);
if (loading) return <ActivityIndicator />;
//render part as below. user is still undefined initially since useEffect part executes after this render part.
return user ? <AuthenticatedNavigator /> : <UnAuthenticatedNavigator />;
};
const-App=()=>{
const[user,setUser]=useState();//user是与用户相关的数据,包括userToken、companyId、email、fullName
const[loading,setLoading]=useState(true);
const getUserData=async()=>{
试一试{
const userData=await AsyncStorage.getItem('@userData');
if(userData!==null){
setUser(JSON.parse(userData));
}
设置加载(假);
}捕获(e){
警报('抱歉!读取用户数据时发生意外错误');
}
};
const setUserData=async(userData)=>{
试一试{
如果(用户数据){
const jsonValue=JSON.stringify(userData);
等待AsyncStorage.setItem('@userData',jsonValue);
setUser(value);//更改状态以便重新渲染
}
}捕获(e){
警报('抱歉!保存用户数据时发生意外错误');
}
};
useffect(()=>{
getUserData();//这在渲染部分之后执行。我希望它在渲染部分之前执行
}, []);
如果(装载)返回;
//如下所示呈现部分。由于useEffect部分在此呈现部分之后执行,因此用户最初仍然未定义。
返回用户?:;
};
屏幕将至少呈现一次,因此您可以使用此模式使用ActivityIndicator显示加载,直到用户加载为止
const App = () => {
const [user, setUser] = useState(); //user is user related data including userToken, companyId, email, fullName
const [loading, setLoading] = useState(true);
const getUserData = async () => {
try {
const userData = await AsyncStorage.getItem('@userData');
if (userData !== null) {
setUser(JSON.parse(userData));
}
setLoading(false);
} catch (e) {
alert('Sorry! An unexpected error has occurred while reading user data.');
}
};
const setUserData = async (userData) => {
try {
if (userData) {
const jsonValue = JSON.stringify(userData);
await AsyncStorage.setItem('@userData', jsonValue);
setUser(value); //change state so re-rendering happens
}
} catch (e) {
alert('Sorry! An unexpected error has occurred while saving user data.');
}
};
useEffect(() => {
getUserData(); //this executes after the render part. I would like it to execute before the render part
}, []);
if (loading) return <ActivityIndicator />;
//render part as below. user is still undefined initially since useEffect part executes after this render part.
return user ? <AuthenticatedNavigator /> : <UnAuthenticatedNavigator />;
};
const-App=()=>{
const[user,setUser]=useState();//user是与用户相关的数据,包括userToken、companyId、email、fullName
const[loading,setLoading]=useState(true);
const getUserData=async()=>{
试一试{
const userData=await AsyncStorage.getItem('@userData');
if(userData!==null){
setUser(JSON.parse(userData));
}
设置加载(假);
}捕获(e){
警报('抱歉!读取用户数据时发生意外错误');
}
};
const setUserData=async(userData)=>{
试一试{
如果(用户数据){
const jsonValue=JSON.stringify(userData);
等待AsyncStorage.setItem('@userData',jsonValue);
setUser(value);//更改状态以便重新渲染
}
}捕获(e){
警报('抱歉!保存用户数据时发生意外错误');
}
};
useffect(()=>{
getUserData();//这在渲染部分之后执行。我希望它在渲染部分之前执行
}, []);
如果(装载)返回;
//如下所示呈现部分。由于useEffect部分在此呈现部分之后执行,因此用户最初仍然未定义。
返回用户?:;
};
您是否尝试使用了useLayoutEffect
?否。我应该用useLayoutEffect替换useEffect吗?无论如何,我会研究它,看看它是否解决了我的问题。我尝试过,但useLayoutEffect
似乎仍然会引起闪烁,就像useffect
一样。如果我想render part
在componentDidMount
部分之后执行,最好的解决方案可能是使用基于类的应用程序组件,这样就不会闪烁发生。为什么不在加载用户之前设置加载标志并显示activityindicator?您是否尝试使用useLayoutEffect
?否。我是否应该用useLayoutEffect替换useEffect?无论如何,我会研究它,看看它是否解决了我的问题。我尝试过,但useLayoutEffect
似乎仍然会引起闪烁,就像useffect
一样。如果我想render part
在componentDidMount
部分之后执行,最好的解决方案可能是使用基于类的应用程序组件,这样就不会闪烁发生。为什么不设置加载标志并在用户加载之前显示activityindicator?我尝试了您的代码,但始终显示activityindicator,即代码行setLoading(false)
从未执行。您是否可以调试并查看是否设置了加载?我在getUserData函数中将其设置为false是的,这是我的错误。我将该行代码放在setUser之后,此时它应该在if(userData!==null)之外。谢谢你的帮助。是否可以显示活动指示器至少2秒