调用子组件React Native(TypeScript)之前传入API数据

问题描述 投票:0回答:1

我正在尝试在父组件中进行 API 调用并将该数据传递给子组件,但我认为子组件在 API 调用完成之前就已渲染,并且我在子组件中接收了

undefined
数据。

具体来说,错误是:

Possible unhandled promise rejection (id: 0):  TypeError: Cannot convert undefined value to object

我想等待 API 调用完成,然后使用该数据将其传递给我的孩子。

这是家长:

const Parent = () => {
    ...
    const [intraday, setIntraday] = useState<IntradayInterface>();
    const [daily, setDaily] = useState<DailyInterface>();
    const [weekly, setWeekly] = useState<WeeklyInterface>();
    const [monthly, setMonthly] = useState<MonthlyInterface>();

    useEffect(() => {
      async function UpdateDetails()
      {
          const intradayJSON = await getIntradayData(newSymbol);
          const dailyJSON = await getDailyData(newSymbol);
          const weeklyJSON = await getWeeklyData(newSymbol);
          const monthlyJSON = await getMonthlyData(newSymbol);
      
          setIntraday(parseIntradayData(intradayJSON));          
          setDaily(parseDailyData(dailyJSON));
          setWeekly(parseWeeklyData(weeklyJSON));
          setMonthly(parseMonthlyData(monthlyJSON));
           
          setIsLoading(false);
      }
      UpdateStockDetails();
    }, []); 

    if(isLoading){
      return <ActivityIndicator size='large' />
    }
    else{
      return (
        <ScrollView style={{ backgroundColor: black}}>
          <View style={{ flex: 1, justifyContent: 'space-between', padding: 10 }}>
          <View>
              <Graph symbol={newSymbol} 
                intraday={intraday!}
                daily={daily!}
                weekly={weekly!}
                monthly={monthly!}/>
          </View>
...

孩子是我的

Graph
组件。

我是否可以让父组件等待 api 调用完成,以便我可以将结果数据传递给子组件

Graph

typescript react-native react-hooks
1个回答
0
投票

Graph
组件所需的所有 props 都可用时,您可以有条件地渲染它。您还应该将所有异步逻辑包含在
try/catch
中,以便处理抛出的异常和被拒绝的 Promise。

示例:

const Parent = () => {
  ...
  const [intraday, setIntraday] = useState<IntradayInterface>();
  const [daily, setDaily] = useState<DailyInterface>();
  const [weekly, setWeekly] = useState<WeeklyInterface>();
  const [monthly, setMonthly] = useState<MonthlyInterface>();

  useEffect(() => {
    async function updateDetails() {
      try {
        const [intradayJSON, dailyJSON, weeklyJSON, monthlyJSON] =
          await Promise.all([
            getIntradayData(newSymbol),
            getDailyData(newSymbol),
            getWeeklyData(newSymbol),
            getMonthlyData(newSymbol)
          ]);
      
        setIntraday(parseIntradayData(intradayJSON));          
        setDaily(parseDailyData(dailyJSON));
        setWeekly(parseWeeklyData(weeklyJSON));
        setMonthly(parseMonthlyData(monthlyJSON));
      } catch(error) {
        // catch and handle/ignore errors/rejections
      } finally {
        // Clear loading status regardless of success/failure
        setIsLoading(false);
      }
    }

    updateStockDetails();
  }, []);

  const canShowGraph = newSymbol && intraday && daily && weekly && monthly;

  if (isLoading) {
    return <ActivityIndicator size='large' />
  } else {
    return (
      <ScrollView style={{ backgroundColor: black }}>
        <View
          style={{
            flex: 1,
            justifyContent: 'space-between',
            padding: 10
          }}
        >
          <View>
            {canShowGraph && (
              <Graph
                symbol={newSymbol} 
                intraday={intraday}
                daily={daily}
                weekly={weekly}
                monthly={monthly}
              />
            )}
          </View>
          ...
        </View>
        ...
      </ScrollView>
    );
  }
};

渲染一些后备 UI 可能也是个好主意,以防加载确实失败并且没有图形数据作为道具传递。

示例:

<View>
  {canShowGraph ? (
    <Graph
      symbol={newSymbol} 
      intraday={intraday}
      daily={daily}
      weekly={weekly}
      monthly={monthly}
    />
  ) : <View>No data.</View>}
</View>
© www.soinside.com 2019 - 2024. All rights reserved.