如何在 react native 中的 react-native-deck-swiper 中传递动态引用?

问题描述

我不习惯使用 ref,所以我有一个问题。我正在使用 react-native-deck-swiper 来显示一些卡片。人们可以通过刷卡投票。尽可能清楚:

  • 我的 swiper 显示一个项目,其他项目来自多个 在我的平面列表中输入
  • 我的项目按项目类型有条件地呈现,如果我的 item 是一个 swiper 类型,我显示一个 swiper,如果它是一个简单的 文本,我正在显示文本等...
  • 所以我的平面列表中可能有多个 swiper

这是显示我的 swipers 的 json :

{
            "id": 577,"type": "copernic","entity": {
                "id": 715,"str_id": "rCckubRTIDz2D3N5wcKW","display_name": "Force Républicaine","name": "Force Républicaine","title": "Dépense publique","description": null,"type": 2,"str_type": "Pour / Contre / Neutre","is_opened": 1,"str_is_opened": "Les utilisteurs peuvent soumettre des propositions","order_propositions_by": 3,"display_Votes": 1,"login_to_Vote": 0,"str_login_to_Vote": "Les utilisateurs ne doivent pas se connecter pour Voter","login_to_send_proposition": 1,"str_login_to_send_proposition": "Les utilisateurs doivent se connecter pour envoyer une proposition","begins_at": "2021-03-02T17:45:55.000000Z","ends_at": null,"propositions": [
                    {
                        "id": 6572,"title": "Pensez-vous qu'il faille annuler la dette COVID ?","description": "","auteur": "Force Républicaine","type": 1,"media_link": null,"video_frame": null
                    },{
                        "id": 6571,"title": "Trouvez-vous la qualité des services publics en France à la hauteur du niveau de la dépense publique du pays ?","video_frame": null
                    }
                ]
            },"is_pinned": 0,"created_at": "2021-03-18T13:27:03.000000Z"
        },

因此,每个 swipers 都可以将 item.entity.iditem.entity.id 作为参考。

我的刷卡器将 item.entity.propositions 显示为卡片。每张卡片都有拇指可以向右、向上或向左投票。当我们点击拇指时,我需要一个 ref 来做一些像 swiperRef.current.swipeRight() 一样的事情,或者通过显示一条消息告诉用户这个刷卡器的每张卡片都被刷过。现在消息显示在所有 swipers 上,这不是我想要的 :)

这是我的 swiper 代码

if (
      item.type === "copernic" &&
      item.entity.str_type === "Pour / Contre / Neutre"
    ) {
       return (
         <View style={styles.swipperWrapper} key={item.id}>
          {isSwipedAll ? (
            <View style={styles.emptycopernic}>
              <View style={styles.emptycopernicColor} />
              <View style={styles.copContainer}>
                <Text style={styles.copTitle}>
                  You have swiped all the cards! Thanx for your participation !
                </Text>
              </View>
            </View>
          ) : (
            <Swiper
              ref={useSwiper}
              //animateCardOpacity
              containerStyle={styles.swiperContainer}
              cards={item.entity.propositions}
              renderCard={(card,index) => (
                <Cardcopernic
                  {...index}
                  copKey={card.id}
                  copTitle={card.title}
                  copDesc={card.description}
                  strid={strid}
                  onPressNo={() => swipeLeft(card.id,index)}
                  onPressMaybe={() => swipetop(card.id,index)}
                  onPressYes={() => swipeRight(card.id,index)}
                />
              )}
              onSwipedLeft={(card) => handleNo(card)}
              onSwipedTop={(card) => handleMaybe(card)}
              onSwipedRight={(card) => handleYes(card)}
              onSwipedAll={onSwipedAllCards}
              cardindex={cardindex}
              stackSize={3}
              stackScale={5}
              showSecondCard
              backgroundColor="white"
              cardVerticalMargin={2}
              disableBottomSwipe
              overlayLabels={{
                left: {
                  title: "Contre",style: {
                    label: {
                      borderColor: "#FF8585",color: "#FF8585",borderWidth: 2,},wrapper: {
                      flexDirection: "column",alignItems: "flex-end",justifyContent: "flex-start",marginTop: 30,marginLeft: -30,right: {
                  title: "Pour",alignItems: "flex-start",marginLeft: 30,top: {
                  title: "Neutre",alignItems: "center",justifyContent: "center",}}
            />
          )}
        </View>
      );

这是向左、向右或顶部刷卡的功能之一:

swipeLeft = async (cardId,index) => {
        console.log("CARdindEX : ",index);

        const cardKey = cardId;
        const strid = item.entity.str_id;
        const token = await AsyncStorage.getItem("token");
        useSwiper.current[strid].swipeLeft(cardId);

        const requestOptions = {
          method: "POST",headers: {
            "Content-Type": "application/json","X-Requested-With": "XMLHttpRequest",Authorization: `Bearer ${token}`,body: JSON.stringify({
            Vote: "contre",proposition_id: `${cardKey}`,consultation_str_id: `${strid}`,}),};

        try {
          let response = await fetch(
            `${c.API_URL_DEV}/copernic/Vote/add`,requestOptions
          );
          let json = await response.json();
          if (index === item.entity.propositions.length - 1) {
            setSwipedAll(true);
            await AsyncStorage.setItem("hasAllSwiped",JSON.stringify(true));
          }
          return json;
        } catch (error) {
          console.error(error);
        }
      };

感谢任何帮助!我有点卡在这里,对裁判不太熟悉 haha​​ x 我的项目是功能组件:)

如果您需要更多信息来帮助,请告诉我! :)

解决方法

尝试将相关的swiper代码封装成一个组件。这将消除对动态引用的需要并正确封装状态。

类似于:

function MySwiper({item}) {
  const swiperRef = useRef(null);
  const [isSwipedAll,setSwipedAll] = useState(false);
  const swipeLeft = useCallback(async (cardId,index) => {
    console.log("CARDINDEX : ",index);

    const cardKey = cardId;
    const strid = item.entity.str_id;
    const token = await AsyncStorage.getItem("token");
    swiperRef.current.swipeLeft(cardId);

    const requestOptions = {
      method: "POST",headers: {
        "Content-Type": "application/json","X-Requested-With": "XMLHttpRequest",Authorization: `Bearer ${token}`,},body: JSON.stringify({
        vote: "contre",proposition_id: `${cardKey}`,consultation_str_id: `${strid}`,}),};

    try {
      let response = await fetch(
        `${c.API_URL_DEV}/copernic/vote/add`,requestOptions
      );
      let json = await response.json();
      if (index === item.entity.propositions.length - 1) {
        setSwipedAll(true);
        await AsyncStorage.setItem("hasAllSwiped",JSON.stringify(true)); // TODO: index this somehow by the item
      }
      return json;
    } catch (error) {
      console.error(error);
    }
  },[item]);

  return (
    <View style={styles.swipperWrapper} key={item.id}>
      {isSwipedAll ? (
        <View style={styles.emptyCopernic}>
          <View style={styles.emptyCopernicColor} />
          <View style={styles.copContainer}>
            <Text style={styles.copTitle}>
              You have swiped all the cards! Thanx for your participation !
            </Text>
          </View>
        </View>
      ) : (
        <Swiper
          ref={useSwiper}
          //animateCardOpacity
          containerStyle={styles.swiperContainer}
          cards={item.entity.propositions}
          renderCard={(card,index) => (
            <CardCopernic
              {...index}
              copKey={card.id}
              copTitle={card.title}
              copDesc={card.description}
              strid={strid}
              onPressNo={swipeLeft}
              onPressMaybe={() => swipeTop(card.id,index)} // UPDATE
              onPressYes={() => swipeRight(card.id,index)} // UPDATE
            />
          )}
          onSwipedLeft={(card) => handleNo(card)} // UPDATE
          onSwipedTop={(card) => handleMaybe(card)} // UPDATE
          onSwipedRight={(card) => handleYes(card)} // UPDATE
          onSwipedAll={onSwipedAllCards}
          cardIndex={cardIndex}
          stackSize={3}
          stackScale={5}
          showSecondCard
          backgroundColor="white"
          cardVerticalMargin={2}
          disableBottomSwipe
          overlayLabels={...}
        />
      )}
    </View>
  );
}

您需要创建其他回调并修复它们在 AsyncStorage 中的状态存储,以便根据每个项目进行键控。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...