Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
160 views
in Technique[技术] by (71.8m points)

javascript - Passing an item ID to a component from keyExtractor

I'm making an app in React Native. There are three components I'm currently concerned with:

AllList.js: A screen comprised of a search bar and a FlatList of RowCard.js instances.

RowCard.js: a custom TouchableHighlight component that displays an item from an API, and displays DrinkPopup.js when tapped by using a state stored in AllList.js.

DrinkPopup.js: A custom Modal component that needs to take an ID from whichever RowCard is tapped and use it to make an API call to get its own data.

I can't figure out how to take the ID from the RowCard or FlatList and pass it to DrinkPopup - how should I do it?

Relevant code for AllList:

 export default function AllList() {
  const [isLoading, setLoading] = useState(true);
  const [drinkData,setDrinkData] = useState([]);
  const [searchValue, onChangeText] = useState(''); //needed for search
  const [reloading, setReloading] = useState(false);
  const [modalVisible, setModalVisible] = useState(false); //normal modal visibility handler

  useEffect (() =>  { 
    fetch('https://www.thecocktaildb.com/api/json/v1/1/search.php?s=' + searchValue)
      .then((response) => response.json())
      .then((json) => setDrinkData(json.drinks))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
      
  },[drinkData]);
  
  return (
    
    <View style = {styles.screen}>
      <View style = {styles.searchSection}>
        <TextInput 
          placeholder="Search Drinks..."  
          style={styles.input}
          onChangeText={text => onChangeText(text)}
          value={searchValue}/>
      </View>
      <FlatList
        data={drinkData}
        keyExtractor={({ idDrink }, index) => idDrink}
        removeClippedSubviews={true}
        initialNumToRender={5}
        renderItem={({ item }) => (
          <RowCard id={item.idDrink} image={item.strDrinkThumb} title={item.strDrink} alcontent={item.strAlcoholic} 
            ingredient1={item.strIngredient1} ingredient2={item.strIngredient2} ingredient3={item.strIngredient3} setModalVisible={setModalVisible}
          />
          
        )}
        extraData={reloading}
        
      />
      <DrinkPopup modalVisible={modalVisible} setModalVisible={setModalVisible}/>
      
    </View>
      
  );

};

Relevant code for RowCard:

const RowCard = (props) => {
    
  return(
      <TouchableHighlight
        style={styles.rowCard}
        activeOpacity={0.6}
        underlayColor={"white"}
        onPress={() => {props.setModalVisible(true) }}
        >

        <View style={styles.rowCard}>
          <Image source={{uri: props.image, width: 150, height: 150}} />
          <View style={styles.textBox}>
            <Text style={styles.titleText}>{props.title}</Text>
            <Text style={styles.ingredient}> Main ingredients: {props.ingredient1}, {props.ingredient2}, {props.ingredient3} </Text>
          </View>
        </View>
      </TouchableHighlight>
    )
  };

Relevant code for DrinkPopup:

const DrinkPopup = (props) => {


  return(
    <Modal isVisible={props.modalVisible}
    onBackdropPress={()=>{props.setModalVisible(false)}} //allows closing modal by tapping outside it or back button
    onBackButtonPress={()=>{props.setModalVisible(false)}} 
    animationIn={"slideInUp"}>  
      <View style={styles.infocard}>
          <View style={styles.titleBox}>
            <Text style={styles.header}>I HAVE NO IDEA WHAT YOU PICKED</Text>
          </View>
      </View>
    </Modal>


  )


}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

How about doing the following, in AllList.js

const [id, setId] = useState(0);
const renderItem = ({ item }) => {
        setId(item.id);

   return (
      <RowCard id={item.idDrink} image={item.strDrinkThumb} title={item.strDrink} alcontent={item.strAlcoholic} 
        ingredient1={item.strIngredient1} ingredient2={item.strIngredient2} ingredient3={item.strIngredient3} setModalVisible={setModalVisible}
      />
    );
  };
    

and in your FLatList call renderItem function like that:

renderItem={()=>renderItem}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...