如何在React-Native中从屏幕获取数据?

kknvjkwl  于 2022-12-04  发布在  React
关注(0)|答案(1)|浏览(205)

我有一个订阅屏幕,其中有一个useEffect挂钩,用于更新isSubbscribed useState。
我在ApprRoot中实现了这个屏幕作为订阅付费墙。我只需要获取这个useState变量isSubscribed,并在appRoot中使用它来查看数据。我如何从订阅屏幕中获取这些数据?
例如在我的AppRoot.jsx中:

const subbed =  *subScreen use State Variable* 
return (

{ subbed ? (
                        <Stack.Navigator>  
                            <Stack.Group>
                                <Stack.Screen
                                    name="SubScreen"
                                    component={SubScreen}
                                    initialParams={{ initialroute: 'Home' }}
                                />
                                </Stack.Group>
                            </Stack.Navigator>  
                        ) : (
                        <NavigationRoot /> 
                        )}
)

jsx有一个如下所示的变量

const [subbed, setSubbed] = useState([]);

我如何在approot文件中使用这个useState?我不能简单地导出它吗?
我希望能够获得useState变量subbed,并使用它来生成适当的屏幕。
下面是完整的子屏幕,其中ownedSubscriptions和Setowned正在从appRoot传递。我需要子屏幕在启动时显示(如果未订阅),但能够在启动时访问,以及不显示(如果ownedSubscriptions为true且不为空)。

const SubScreen = ({ownedSubscriptions,setOwnedSubscriptions}) => {

  const {
    connected,
    subscriptions,
    getSubscriptions,
    currentPurchase,
    finishTransaction,
  } = useIAP();

  console.log('connected: ',connected);

  //[ownedSubscriptions, setOwnedSubscriptions] = set useState(

  const handleGetSubscriptions = () => {
        getSubscriptions({skus: ['sku']}).then( ()=>{
          console.log('Got Subscriptions')
        }).catch( () => {
          console.log('failed to get subscriptions')
        })
      }

  const handleBuySubscription = async (
      productId,
      offerToken,
    ) => {
      if (isPlay && !offerToken) {
        console.warn(
          `There are no subscription Offers for selected product (Only requiered for Google Play purchases): ${productId}`,
        );
      }
      try {
        await requestSubscription({
          sku: productId,
          ...(offerToken && {
            subscriptionOffers: [{sku: productId, offerToken}],
          }),
        });
      } catch (error) {
        if (error instanceof PurchaseError) {
          errorLog({message: `[${error.code}]: ${error.message}`, error});
        } else {
          errorLog({message: 'handleBuySubscription', error});
        }
      }
    };
  
    useEffect(() => {      
      const checkCurrentPurchase = async () => {
        try {
          if (currentPurchase?.productId) {
            await finishTransaction({
              purchase: currentPurchase,
              isConsumable: true,
            });
  
            setOwnedSubscriptions((prev) => [
              ...prev,
              currentPurchase?.productId,
            ]);
          }
        } catch (error) {
          if (error instanceof PurchaseError) {
            errorLog({message: `[${error.code}]: ${error.message}`, error});
          } else {
            errorLog({message: 'handleBuyProduct', error});
          }
        }
      };
  
      checkCurrentPurchase();
    }, [currentPurchase, finishTransaction]);

    console.log(ownedSubscriptions + ' owned') //returns lxm_1999_1m_1w0

    return (
      <ScrollView contentContainerStyle={contentContainerStyle}>
        <State connected={connected} storekit2={isIosStorekit2()} />
  
        <Box>
          <View style={styles.container}>
            <Heading copy="Subscriptions" />
  
            {subscriptions.map((subscription, index) => {
              const owned = ownedSubscriptions.find((pId) => {
                return isAmazon
                  ? pId === constants.amazonBaseSku
                  : pId === subscription.productId;
              });
              return (
                <Row
                  key={subscription.productId}
                  fields={[
                    {
                      label: 'Subscription Id',
                      value: subscription.productId,
                    },
                    {
                      label: 'type',
                      value:
                        'type' in subscription
                          ? subscription.type
                          : subscription.productType,
                    },
                  ]}
                  isLast={subscriptions.length - 1 === index}
                >
                  {owned && <Text>Subscribed</Text>}
                  {!owned &&
                    isPlay &&
                    // On Google Play Billing V5 you might have  multiple offers for a single sku
                    'subscriptionOfferDetails' in subscription &&
                    subscription?.subscriptionOfferDetails?.map((offer) => (
                      <Button
                        title={`Subscribe ${offer.pricingPhases.pricingPhaseList
                          .map((ppl) => ppl.billingPeriod)
                          .join(',')}`}
                        onPress={() => {
                          handleBuySubscription(
                            subscription.productId,
                            offer.offerToken,
                          );
                        }}
                      />
                    ))}
                  {!owned && (isIos || isAmazon) && (
                    <Button
                      title="Subscribe"
                      onPress={() => {
                        handleBuySubscription(subscription.productId);
                      }}
                    />
                  )}
                </Row>
              );
            })}
          </View>
  
          <Button
            title="Get the subscriptions"
            onPress={handleGetSubscriptions}
          />
        </Box>
      </ScrollView>
    );
};

const styles = StyleSheet.create({
  container: {
    marginBottom: 20,
  },
});

export default SubScreen;
6xfqseft

6xfqseft1#

我认为最简单的方法是在父组件中定义状态变量(如apRoot),并将其作为props和setSubbed一起传递到屏幕(如2个props)。
因此,您的AppRoot.jsx应该如下所示:

const [subbed, setSubbed] = useState([]);
return (

{ subbed ? (
                        <Stack.Navigator>  
                            <Stack.Group>
                                <Stack.Screen
                                    name="SubScreen"
                                    initialParams={{ initialroute: 'Home' }}>
                                    {props => <SubScreen {...props} subbed={subbed} setSubbed={setSubbed} />}
                                </Stack.Screen>
                                </Stack.Group>
                            </Stack.Navigator>  
                        ) : (
                        <NavigationRoot /> 
                        )}
)

现在,您可以从子组件更新它(使用setSubbed),并从父组件使用它。
您的子组件如下所示:

function SubScreen({subbed, setSubbed}) {}
// or
const SubScreen = ({subbed, setSubbed}) => {}

如果您需要从其他几个组件,甚至嵌套组件中获取它,则可能需要查看上下文。

相关问题