在渲染JSX零件之前先进行useEffect触发

时间:2020-10-11 15:52:30

标签: react-native use-effect

我在expo react native应用程序中有一个功能组件,如下面的代码所示。我遇到的麻烦是render part,即JSX出现的位置要在useEffect内部的代码之前执行。

我想在useEffect部分之后执行渲染部分,以使屏幕不会闪烁,因为先显示了UnAuthenticatedNavigator,然后当useEffect执行AuthenticatedNavigator显示的其他组件时,大约一秒钟之后。

问题:如何确保在下面的App组件的render part部分之后执行useEffect

App.js

  const App = () => {
  
  const [user, setUser] = useState();//user is user related data including userToken, companyId, email, fullName
  
  const getUserData = async () => {
    try {
      const userData = await AsyncStorage.getItem('@userData');

      if (userData !== null) {
        setUser(JSON.parse(userData));
      }

    } 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
  }, []);


  //render part as below. user is still undefined initially since useEffect part executes after this render part.
  return (
    (user ? <AuthenticatedNavigator /> : <UnAuthenticatedNavigator />)
  );
};

1 个答案:

答案 0 :(得分:2)

屏幕将至少渲染一次,因此您可以使用此模式通过ActivityIndi​​cator显示加载,直到加载用户为止。

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 />;
};