reactjs 当我切换到新类别时,将currentItem的值设置为零

xe55xuns  于 2023-08-04  发布在  React
关注(0)|答案(1)|浏览(58)

所以我在做一个新闻应用。布局基本上是基于卡片的,我们可以滚动到那里访问新闻。
有一个变量currentItem用于跟踪当前索引。
问题是,当我切换到一个新的索引时,currentItem保留了与前一个类别中相同的值,并继续只从该索引阅读新闻数组。
我尝试在类别更改时将currentItem设置为0,但这会导致应用程序的布局损坏。
Newscard.js

import React, { useEffect, useState,useContext } from 'react'
import { View, StyleSheet, Text, Dimensions, Animated, Image, Alert } from 'react-native'
import AuthorInfo from './AuthorInfo'
import Icon from 'react-native-vector-icons/FontAwesome'
import { PanGestureHandler, State, TapGestureHandler } from 'react-native-gesture-handler'
import FullPageNews from '../pages/FullPageNews/FullPageNews'
import {useBetweenPages,BetweenTypes} from 'between-pages'
import newsContext from '../context/newsContext'
const ScreenWidth = Dimensions.get("window").width

//edit the function below to include only a certain count of characters to the string

function reduceStringToWordCount(inputString, wordCount) {
    const wordsArray = inputString.trim().split(/\s+/);
    const reducedWordsArray = wordsArray.slice(0, wordCount);
    const reducedString = reducedWordsArray.join(" ");
    return reducedString;
}

function reduceStringToCharacterCount(inputString, charCount) {
    if (inputString.length <= charCount) {
        return inputString;
    } else {
        const reducedString = inputString.slice(0, charCount);
        return reducedString;
    }
}

const Newscard = (props) => {
    const translateX = new Animated.Value(0);
    const [isDragging, setIsDragging] = React.useState(false);
    const [liked, setLiked] = useState(false);
    const [bookmarked, setBookmarked] = useState(false);
    const doubleTapRef = React.useRef(null);
    const context = useContext(newsContext);
    const {colors,currentItem} = context
    const {startTransition} = useBetweenPages(<FullPageNews context={context}/>)

    const handleToNewsPage = () => {
        startTransition(
            {
                type:BetweenTypes.SPRING,
                duration: 300,
                endAnimation:true
            },
            ()=>{
                props.navigation.navigate("FullPageNews");
            }
        );
    }

    return (
        ((props.index == currentItem) || (props.index == currentItem + 1)) &&
        <PanGestureHandler
            enabled={props.index == currentItem}
            maxPointers={1}
            onGestureEvent={
                Animated.event(
                    [
                        {
                            nativeEvent: {
                                translationX: translateX,
                            },
                        },
                    ],
                    {
                        useNativeDriver: true,
                    }
                )
            }

            onHandlerStateChange={(e) => {
                if (e.nativeEvent.state === State.BEGAN) {
                    setIsDragging(true);
                }

                if (e.nativeEvent.state === State.ACTIVE) {
                    console.log("done")

                }
                if (e.nativeEvent.state === State.END) {
                    console.log("end")
                    setIsDragging(false);
                    if (e.nativeEvent.translationX < -50) {
                        props.setActiveIndex(currentItem + 1);
                    }
                    else if (e.nativeEvent.translationX > 50) {
                        props.setActiveIndex(currentItem - 1);
                    }
                }
            }}

        >
            <Animated.View style={{
                backgroundColor: colors[props.index % 8],
                paddingHorizontal: 25,
                paddingBottom: 10,
                paddingTop: 20,
                width: ScreenWidth/1.15,
                //height:Dimensions.get("window").height/2.1,
                marginBottom: 20,
                borderRadius: 25,
                display: 'flex',
                flexDirection: 'column',
                position: 'absolute',
                zIndex: props.zIndex,
                left: "-42%",
                transform: [
                    { translateX: (isDragging) ? translateX : props.animationProps[0] },
                    { rotate: props.animationProps[1] },
                    { translateY: props.animationProps[2] },
                ],
                opacity: props.animationProps[3],
            }
            }>
                <TapGestureHandler
                    enabled={props.index == currentItem}
                    onHandlerStateChange={(e) => {
                        if (e.nativeEvent.state === State.END) {
                            props.navigation.navigate("FullPageNews");
                            //handleToNewsPage();
                        }
                    }
                    }

                    waitFor={doubleTapRef}
                >
                    <TapGestureHandler
                        enabled={props.index == currentItem}
                        numberOfTaps={2}
                        ref={doubleTapRef}
                        onHandlerStateChange={(e) => {
                            if (e.nativeEvent.state === State.ACTIVE) {
                                setLiked(!liked);
                            }
                        }
                    }
                    >
                    <View>
                        <Text style={{
                            fontFamily: "Manrope-Bold",
                            color: "black",
                            fontSize: 30,
                            lineHeight: 40
                        }}>
                            {(props.news.description !== null) ? reduceStringToWordCount(props.news.title, 10) + "..." : props.news.title}
                        </Text>
                        <Text style={{
                            marginTop: 20,
                            fontFamily: "Manrope-Regular",
                            color: "#0000008e",
                            fontSize: 15,
                        }}>
                            {props.news.publishedAt.split("T")[0]}
                        </Text>
                        <View>
                            <AuthorInfo author={props.news.source.name} reduceStringToCharacterCount={reduceStringToCharacterCount} />
                        </View>
                        {!(props.news.description === null || props.news.description == "") && <View style={{
                            marginTop: 20
                        }}>
                            <Text style={{
                                color: 'black',
                                fontSize: 15,
                                fontFamily: "Manrope-Medium",

                                lineHeight: 25
                            }}>
                                {reduceStringToWordCount(props.news.description, 30) + "..."}
                            </Text>
                        </View>}

                        <View style={{
                            marginTop: 50
                        }}>
                            <View style={{
                                position: 'relative',
                                alignSelf: "flex-end",
                                display: 'flex',
                                flexDirection: 'row'
                            }}>
                                <TapGestureHandler
                                    enabled={props.index == currentItem}
                                    onHandlerStateChange={(e) => {
                                        if (e.nativeEvent.state === State.ACTIVE) {
                                            setLiked(!liked);
                                        }
                                    }
                                    }
                                >
                                    <View style={styles.actionButtons}>
                                        <Icon name={liked ? "thumbs-up" : "thumbs-o-up"} size={18} color="black" />
                                    </View>
                                </TapGestureHandler>

                                <TapGestureHandler
                                    enabled={props.index == currentItem}
                                    onHandlerStateChange={(e) => {
                                        if (e.nativeEvent.state === State.ACTIVE) {
                                            setBookmarked(!bookmarked);
                                        }
                                    }
                                    }
                                >
                                <View style={styles.actionButtons}>
                                    <Icon name={bookmarked ? "bookmark" : "bookmark-o"} size={18} color="black" />
                                </View>
                                </TapGestureHandler>

                                <View style={styles.actionButtons}>
                                    <Icon name="share-square-o" size={18} color="black" />
                                </View>
                            </View>
                        </View>
                    </View>
                    </TapGestureHandler>
                </TapGestureHandler>
            </Animated.View>
            {/* </FlingGestureHandler> */}
        </PanGestureHandler>
    );
}

const styles = StyleSheet.create({
    actionButtons: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        borderWidth: 0.5,
        borderColor: 'black',
        borderStyle: 'solid',
        borderRadius: 50,
        width: 30,
        height: 30,
        marginLeft: 10
    }
})
export default Newscard

字符串
NewscardHolder.js

import React, { useState, useEffect, useContext } from 'react'
import newsContext from '../context/newsContext'
import Newscard from './Newscard'
import { Alert, Animated, Dimensions, View } from 'react-native'


const width = Dimensions.get("window").width
const height = Dimensions.get("window").height

const NewscardHolder = (props) => {
  const context = useContext(newsContext)
  const { fetchData,news,dataReady,category,colors,currentItem,setCurrentItem } = context;
  const scrollXIndex = React.useRef(new Animated.Value(0)).current;
  const scrollXAnimated = React.useRef(new Animated.Value(0)).current;
  // const [activeData, setActiveData] = useState([]);
  const [dataNeeded, setDataNeeded] = useState(false);

  console.log("Newscardholder component built")
  useEffect(() => {
    Animated.spring(scrollXAnimated, {
      toValue: scrollXIndex,
      useNativeDriver: true,
      speed: 20
    }).start();
  }, [])

  useEffect(() => {
    fetchData()
  }, [category])

  console.log(news.length + " NEws length")
  const setActiveIndex = React.useCallback((activeIndex) => {
    if (activeIndex == -1 || activeIndex == news.length) {
      return;
    }

    console.log(activeIndex)
    setCurrentItem(activeIndex)
    scrollXIndex.setValue(activeIndex);
  })
  return (
    <View style={
      {
        height: height/1.50
      }
    }>
      {
        dataReady && news.map((item, index) => {
          const inputRange = [index - 1, index, index + 1];
          const translateX = scrollXAnimated.interpolate({
            inputRange,
            outputRange: [70, 0, -width - 50],
          });
          const zIndex = news.length - index;
          const scale = scrollXAnimated.interpolate({
            inputRange,
            outputRange: [0.8, 1, 1],
          });

          const rotate = scrollXAnimated.interpolate({
            inputRange,
            outputRange: ['10deg', '0deg', '-10deg'],
          });

          const translateY = scrollXAnimated.interpolate({
            inputRange,
            outputRange: [20, 0, 0],
          });

          const opacity = scrollXAnimated.interpolate({
            inputRange,
            outputRange: [1 - 1 / 2, 1, 1],
          });
          return (
            <Newscard
              key={index}
              index={index}
              news={item}
              animationProps={[translateX, rotate, translateY, opacity]}
              zIndex={zIndex}
              setActiveIndex={setActiveIndex}
              navigation = {props.navigation}
            />

          )
        }
        )
      }
    </View>
  )
}

export default NewscardHolder


GitHub repo是:https://github.com/amalthomas-exe/newsapp

chhkpiq4

chhkpiq41#

我假设你的对象“currentItem”依赖于category状态,每当category被改变时,“currentItem”应该被设置为零。我希望我理解正确。如果是的话,你可以尝试一件事并改变:

useEffect(() => {
    fetchData()
  }, [category])

字符串

useEffect(() => {
    fetchData()
    setCurrentState(0)
  }, [category])


因为,每当类别改变时,我们的CurrentState也会得到更新

相关问题