簡體   English   中英

我在反應本機應用程序中更新 useState 后,網格中的項目沒有更新

[英]Items in grid are not updating after I update the useState in react native applcation

我有一個反應原生項目。 我的 react native 項目的一部分是我創建的網格。 當用戶單擊網格中的項目時,我想更新我在 state const [selectedHomeTypes, setSelectedHomeTypes] = useState(['Houses'])中設置的數組。

當我向數組中添加一個項目時,我希望它更新網格,以便數組中的所有項目都具有藍色背景。 如果selectedHomeTypes中有 1 項,則網格中的 1 項具有藍色背景。 如果我向selectedHomeTypes添加第二個項目,我希望網格中的兩個項目具有藍色背景並在我取消選擇從數組中刪除的項目時出售。

現在正在發生的事情是selectedHomeTypes正在像往常一樣更新,因此當單擊不在 state 中的項目時,它將被添加到數組中,並且與 unslelect 相同。 問題是項目的背景 colors 根本沒有更新,無論發生什么,只有默認項目有藍色背景。 視覺上沒有任何變化......

主屏幕:

const [selectedHomeTypes, setSelectedHomeTypes] = useState(['Houses'])
const updateSelectedHomeTypes = (selected) => {
  let selectedHome = selectedHomeTypes
  if(selectedHome.length == 0){
    setSelectedHomeTypes(['Houses'])
  }
  if(selectedHome.includes(selected)){
    let target = selectedHome.indexOf(selected)
    selectedHome.splice(target, 1)
    if(selectedHome.length == 0){
      setSelectedHomeTypes(['Houses'])
    } else {
      setSelectedHomeTypes(selectedHome)
    }
  } else {
    selectedHome.push(selected)
    setSelectedHomeTypes(selectedHome)
  }
}

  return (
    <View style={styles.filterContainer}>
      <ScrollView style={styles.scrollContainer}>
        <View style={styles.header}>
          <Text style={styles.label}>
            Filter
          </Text>
          <TouchableOpacity onPress={() => {resetFilter()}}>
            <Text style={[styles.label, styles.blueText]}>
              Reset
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.sectionContainer}>
          <FlatList 
            style={styles.homeTypeContainer}
            data={homeTypeOptions1}
            keyExtractor={(item) => item.key}
            numColumns={numberOfColumns}
            renderItem={(item) => {
              return(               
                <GridItemComponent 
                  item={item} 
                  updateSelectedHomeTypes={updateSelectedHomeTypes}
                  selectedHomeTypes={selectedHomeTypes}
                />
              )}}
          />
        </View>
      </ScrollView>
      <TouchableOpacity onPress={() => {applyFilters()}}>
        <View style={styles.buttonContainer}>
          <Text style={styles.buttonText}>Apply Filters</Text>
        </View>
      </TouchableOpacity>
    </View>
  )

網格項目組件:

const GridItemComponent = (props) => {
  const {
    item,
    updateSelectedHomeTypes,
    selectedHomeTypes
  } = props

  return(
    <>
      {
        selectedHomeTypes.includes(item.item.value) ? <TouchableOpacity  style={styles.itemContainerBlue} onPress={() => {updateSelectedHomeTypes(item.item.value)}}>
                                                        <View style={styles.item}>
                                                          <Image style={styles.icon} source={item.item.image}/>
                                                          <Text style={styles.label}>{item.item.value}</Text>
                                                        </View>
                                                      </TouchableOpacity>
                                                    : <TouchableOpacity  style={styles.itemContainer} onPress={() => {updateSelectedHomeTypes(item.item.value)}}>
                                                        <View style={styles.item}>
                                                          <Image style={styles.icon} source={item.item.image}/>
                                                          <Text style={styles.label}>{item.item.value}</Text>
                                                        </View>
                                                      </TouchableOpacity>
          }
    </>
  )
}

屬性類型選項列表:

const numberOfColumns = 3

const homeTypeOptions1 = [
  {
    key: 1,
    value: 'Houses',
    image: require('./src/assets/home.png')
  },
  {
    key: 2,
    value: 'Condos',
    image: require('./src/assets/building.png')
  },
  {
    key: 3,
    value: 'Lot/Land',
    image: require('./src/assets/management.png')
  },
  {
    key: 4,
    value: 'Multi-family',
    image: require('./src/assets/multi-family.png')
  },
  {
    key: 5,
    value: 'Manufactured',
    image: require('.//src/assets/tiny-house.png')
  },
  {
    key: 6,
    value: 'Townhomes',
    image: require('.//src/assets/townhouse.png')
  }
]

如下圖所示, selectedHomeTypes在數組中有 3 個項目,但只有 1 個項目被突出顯示。 我在嘗試動態更新所選項目的背景顏色時遇到問題

已選擇 3 項,但 1 項具有藍色背景

乍一看,我認為這是問題所在:

當你這樣做時:

selectedHome.push(selected)
setSelectedHomeTypes(selectedHome)

React 不會重新渲染,因為您將selectedHomeTypes設置為已經在 state 中的相同數組。

您已將新條目推入其中,但 React 正在舊 state 和新 state 之間進行身份比較,以確定是否需要重新渲染。 在這種情況下newArray === oldArray所以它不會觸發更新。

您可以通過傳播到一個新數組(並附加新項目而不是調用 push)來避免這種情況:

setSelectedHomeTypes([...selectedHome, selected])

使用之前的值更新 state 時,請使用回調參數(以避免過時的 state 值)。

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

它應該是

this.setState(state=>
    ({selectedHomeTypes: state.selectedHomeTypes.concat(selected)})
);

如果要更新 state 屬性,使用另一個 state 屬性,最好使用 class 組件。

State 對 arrays 的更新應該使用返回一個新數組的方法來完成( push不會,而concat會)。

請參閱這篇綜合文章以了解如何在 React 中更新 state arrays。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM