Reactjs 在渲染组件之前对本机获取作出反应

Reactjs 在渲染组件之前对本机获取作出反应,reactjs,react-native,react-navigation,render,use-effect,Reactjs,React Native,React Navigation,Render,Use Effect,我正在创建一个RET本机应用程序,它连接到一个API,从中获取数据 我正在使用React导航来处理导航。该应用程序有一个堆栈导航器和一个底部选项卡导航器。StackNavigator有4个屏幕: SignupScreen处理创建帐户 LoginScreen用于handlong登录 SplashScreen检查本地令牌并自动登录用户 一个LoadingScreen,它触发对API的初始获取调用,将响应存储在状态中,并导航到MainFlow屏幕 包含选项卡导航器的MainFlow屏幕 TabNa

我正在创建一个RET本机应用程序,它连接到一个API,从中获取数据

我正在使用React导航来处理导航。该应用程序有一个堆栈导航器和一个底部选项卡导航器。
StackNavigator
有4个屏幕:

  • SignupScreen
    处理创建帐户
  • LoginScreen
    用于handlong登录
  • SplashScreen
    检查本地令牌并自动登录用户
  • 一个
    LoadingScreen
    ,它触发对API的初始获取调用,将响应存储在状态中,并导航到
    MainFlow
    屏幕
  • 包含
    选项卡导航器的
    MainFlow
    屏幕
TabNavigator
有两个屏幕,
FeedScreen
Account
More
,其中初始屏幕为
FeedScreen

注册/登录/本地流都工作正常

问题:一旦用户成功登录,加载屏幕将触发API调用,但
MainFlow
组件将在数据处于状态之前呈现。由于
MainFlow
中的组件需要数据,因此会引发错误。如何仅在数据存在时才渲染
FeedScreen
组件

加载屏幕中
我正在从上下文对象
QuestionContext
触发对
useffect
的API调用:

const LoadingScreen = ({ navigation }) => {
  const [loading, setLoading] = useState(true);
  const { state: authState } = useContext(AuthContext);
  const { getQuestionsForUser, getAllQuestions } = useContext(QuestionContext);

  useEffect(() => {
    getAllQuestions();
  }, []);

  return (
    <View style={styles.container}>
      <YonStatusBar backgroundColor="#310B3B" />
      <Image source={splashLogo} containerStyle={styles.splashLogo} />
      <ActivityIndicator />
    </View>
  );
};

export default LoadingScreen;
getAllQuestions
工作正常:API调用成功,我可以看到响应存储在状态。但是,在这之前,它会导航到
MainFlow

最后,这是
FeedScreen

const getAllQuestions = (dispatch) => {
  return async () => {
    try {
      const token = await AsyncStorage.getItem('token');
      const config = { headers: { Authorization: `Bearer ${token}` } };
      const response = await yonyonApi.get(`/questions`, config);
      dispatch({ type: 'GET_ALL_QUESTIONS', payload: response.data });
      RootNavigation.navigate('MainFlow');
    } catch (e) {
      console.log(e);
    }
  };
};
const FeedScreen = () => {
  const { state: questionState } = useContext(QuestionContext);

  return (
    <ScrollView style={styles.container}>
      {console.log(questionState.questions)}
      <View style={styles.listContainer}>
        <QuestionCard />
      </View>
    </ScrollView>
  );
};

export default FeedScreen;
const FeedScreen=()=>{
const{state:questionState}=useContext(QuestionContext);
返回(
{console.log(questionState.questions)}
);
};
导出默认FeedScreen;
FeedScreen
呈现需要
questionState
中数据的
QuestionCard
。这就是引发错误的原因:在数据处于状态之前呈现
问题卡


当必要的数据处于状态时,如何使导航仅导航到
FeedScreen
?或者,在数据不存在时,呈现除
问题卡
以外的其他内容,并且一旦数据处于
问题状态
呈现
问题卡

对于我,我将使用屏幕而不是两个屏幕,如下所示:

 const FeedScreen = () => {

  const [loading, setLoading] = useState(true);
  const { state: authState } = useContext(AuthContext);
  const [data, setData] = useState([]);

const getAllQuestions = (dispatch) => {
  return async () => {
    try {
      const token = await AsyncStorage.getItem('token');
      const config = { headers: { Authorization: `Bearer ${token}` } };
      const response = await yonyonApi.get(`/questions`, config);
      setData(response.data)
      setLoading(false)
    } catch (e) {
      console.log(e);
    }
  };
};
  useEffect(() => {
    getAllQuestions();
  }, []);

      return (
        <ScrollView style={styles.container}>
          {
            (loading)?
             <ActivityIndicator/>
             :
             <View style={styles.listContainer}>
                <QuestionCard  data={data}/>
              </View>
           }
        </ScrollView>
      );
    };

    export default FeedScreen;
const FeedScreen=()=>{
const[loading,setLoading]=useState(true);
const{state:authState}=useContext(AuthContext);
const[data,setData]=useState([]);
const getAllQuestions=(调度)=>{
返回异步()=>{
试一试{
const token=await AsyncStorage.getItem('token');
const config={headers:{Authorization:`Bearer${token}`};
const response=wait yonapi.get(`/questions`,config);
setData(response.data)
设置加载(错误)
}捕获(e){
控制台日志(e);
}
};
};
useffect(()=>{
getAllQuestions();
}, []);
返回(
{
(装货)?
:
}
);
};
导出默认FeedScreen;

为什么不将上下文的初始状态设置为
null
,如果组件不是
null
,则呈现组件

const [questionState, setQuestionState] = useState(null); 

...

const FeedScreen = () => {
  const { state: questionState } = useContext(QuestionContext);

  return (
    <ScrollView style={styles.container}>
      {!!questionState?.questions && console.log(questionState.questions)}
      <View style={styles.listContainer}>
        <QuestionCard />
      </View>
    </ScrollView>
  );
};

export default FeedScreen;
const[questionState,setQuestionState]=useState(null);
...
常量FeedScreen=()=>{
const{state:questionState}=useContext(QuestionContext);
返回(
{!!questionState?.questions&&console.log(questionState.questions)}
);
};
导出默认FeedScreen;

感谢您的支持。救命啊。但是,这不允许我使用存储在上下文中的状态变量。我不想在屏幕中创建本地状态,而是在上下文中使用本地状态。目前,上下文负责所有异步操作,例如进行API调用。如何在屏幕中等待所有这些操作完成并填充状态,然后再呈现QuestionCard组件?非常感谢。