Как изменить стиль только одного элемента в плоском списке с помощью крючков и функциональных компонентов

#reactjs #react-native #react-native-flatlist #react-component

Вопрос:

Я пытаюсь реализовать простой листинг, используя крючки и функциональные компоненты. Я хочу, чтобы элемент, по которому щелкнули, был выделен, и если там уже был выделен другой элемент, я хочу, чтобы он был выделен. Я получаю данные dumy с первым элементом, уже выбранным из массива объектов, как

     const CategoriesData = [
  {
    id : "1",
    image : require("../images/pizza-icon.png"),
    title : "Pizza",
    selected : true,
  },
  {
    id : "2",
    image : require("../images/shrimp-icon.png"),
    title : "Sea Food",
    selected : false,
  },
  {
    id : "3",
    image : require("../images/soda-icon.png"),
    title : "Drinks",
    selected : false,
  },
  {
    id : "4",
    image : require("../images/pizza-icon.png"),
    title : "Pizza",
    selected : false,
  },
  {
    id : "5",
    image : require("../images/shrimp-icon.png"),
    title : "Sea Food",
    selected : false,
  },
  {
    id : "6",
    image : require("../images/soda-icon.png"),
    title : "Drinks",
    selected : false,
  },
]

export default CategoriesData;
 

Я включил плоский список в качестве компонента в компонент класса, как

     export default class App extends React.Component {
  state = {
    fontsLoaded : false
  }

  loadfonts = async() => {
    await Font.loadAsync(customFonts)
    this.setState({fontsLoaded : true})
  }

  componentDidMount(){
    this.loadfonts()
  }

  componentWillUnmount(){
    this.setState({fontsLoaded: false})
  }
  render(){
    //console.log(colors.secondary)
    if(this.state.fontsLoaded)
    {
      return(
        <View style = {styles.container}>
          <ScrollView contentContainerStyle= {{paddingBottom : 20}} nestedScrollEnabled = {true}>
            
            <CategoriesList/>
            
          </ScrollView>
          <StatusBar style="dark" />
        </View>
      )
    }
    else
    {
      return (
          <Apploading/>
      )
    }

  }
}
 

the flatlist in question is as follows, although I am getting it to get highlighted on clicks and de highlighted on another click but cant seem to understand the logic I would need so that when I click on another item, the previously highlighted item is removed

 const CategoriesList = ()=> (
  <View style = {styles.categoriesListContainer}>
    <FlatList
      contentContainerStyle={{ paddingRight :120, /*backgroundColor : "blue",*/  }}
      data = {categoriesData}
      renderItem = {(object) => <RenderCategories data = {object}/>}
      //keyExtrator = {(item,index) => index.toString()}
      horizontal = {true}/>
  </View>

)


const RenderCategories = (obj) => {
  //console.log(obj.data.item)

  const[selected, setSelected] = useState(obj.data.item.selected)
  const[selectedId, setSelectedId] = useState(1)
  //const[dataupdated, setDataUpdated] =useState(false)
  //const [previousId, setPreviousId] = useState(null)
  //const[flag, setFlag]  = useState(false)

  // console.log("previousID in function:", previousId)
  // console.log("selectedId in function:", selectedId)
  // console.log("selected in function:", selected)
  // console.log("obj.id in function:", obj.data.item.id, "nn")
   const onPress = (id)=> {
     console.log("selected : ", selected)
     console.log("selectedID :", id)
     //setPreviousId(selectedId)

     setSelected(previous=> !previous)
     setSelectedId(id)


   }
   // useEffect(()=> {
   //    //setDataUpdated(previous => !previous)
   // }, [selected, selectedId])

  return (

    <TouchableOpacity onPress = {()=>onPress(obj.data.item.id)}>
      <View style = {[styles.listItems, {backgroundColor : selected ? colors.primary : "#fff"}]} key = {obj.data.item.id}>
        <Image resizeMode = "stretch" source = {obj.data.item.image} style = {styles.listItemImage}/>
        <Text style = {styles.listItemTitle}>{obj.data.item.title}</Text>
        <View
          style = {[styles.iconwrapper, {backgroundColor : selected ? "#fff" : colors.secondary}]}>
          <Feather name = "chevron-right" size = {8}
            style = {[styles.categoryiconselect, {backgroundColor : selected ? "#fff" : colors.secondary}]}/>
        </View>
      </View>
    </TouchableOpacity>

  )
}