Checked - Unchecked doesn't working in ListView - React Native

梦想的初衷 提交于 2019-11-27 07:31:10

问题


friend I Will integrated checked - unchecked in listView. So that When user click on checked then store the data in Array and unchecked then i will remove the data. Its working fine, But the UI Will not updated after checked - unchecked.

<List containerStyle={{marginTop : 0 , borderBottomWidth : 0 , borderBottomColor : 'black', borderTopWidth : 0}}>
  <FlatList
    data={this.state.list}
    renderItem={({ item }) => (
      <ListItem containerStyle={{height: 80, backgroundColor : 'transparent', borderBottomWidth : 0, borderTopWidth : 0}}
        title={
          <View style={styles.titleView}>
            <Text style={styles.ratingText}>{item.iWorkerID.vFirstName}</Text>
          </View>
        }
        rightIcon={
           <TouchableOpacity onPress = {() => this.selectedWorker(item)} style={{width: 30, height: 30 , marginTop : 10, marginRight : 30}}>
             <Image style = {{width: 30, height: 30}} source={this.state.selectedList.includes(item) ? require("./Images/uncheckd.png") : require("./Images/checked.png")}/>
             {/* {this.state.selectedList.includes(item) && <Image style = {{width: 30, height: 30}} source={require("./Images/uncheckd.png")}/>}
             {!this.state.selectedList.includes(item) && <Image style = {{width: 30, height: 30}} source={require("./Images/checked.png")}/>} */}

           </TouchableOpacity>
        }
        avatar={<Avatar
          rounded
          medium
          containerStyle={{marginLeft: 30}}
          source={{uri: Globle.IMAGE_URL+item.vProfileImage}}
          activeOpacity={0.7}
        />}
      />
    )}
  />
</List>

And on the check/uncheck button, I will add/remove object from array,

selectedWorker = (data) =>{
  console.log('data is ', data);

  if (!this.state.selectedList.includes(data)) {
      // this.setState({ selectedList : [...this.state.selectedList , data]})
      this.state.selectedList.push(data);
  } else {

    var index = this.state.selectedList.indexOf(data);
    if (index > -1) {
        this.state.selectedList.splice(index, 1);
    }
  }

  this.setState({list : this.state.list})
  console.log('selected list' , this.state.selectedList);
}

Main Issue : Want to update image checked/unchecked according to selectedList array, How can i Update item in listView.

What to do inside selectedWorker method.

GIF :


回答1:


you are using Flatelist inside List, Both are a component to listing items. you can use List or Flatelist, not both. I hope it will help you..

I try to make Demo similar to that you want.

constructor(props) {
    super(props)
    this.state = {
        list: [
            {
                id: 1,
                name: "Harpal Singh Jadeja",
                avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
            },
            {
                id: 2,
                name: "Kirit Mode",
                avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
            },
            {
                id: 3,
                name: "Rajiv Patil",
                avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
            },
            {
                id: 4,
                name: "Chetan Doctor",
                avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
            }]


    };
};


renderListItem = (index, item) => {
    return (
        <View style={styles.notification_listContainer}>
            <Image source={{uri: item.avtar, cache: 'force-cache'}}
                   style={circleStyle}/>

            <View style={{flex: 1, paddingLeft: 10, justifyContent: 'center'}}>
                <Label roboto_medium
                       align='left'
                       color={Color.TEXT_PRIMARY}
                       numberOfLines={1}>
                    {item.name}
                </Label>
                <Label roboto_medium
                       small
                       align='left'
                       color={Color.TEXT_SECONDARY}
                       mt={8}>
                    Programmer
                </Label>
            </View>

            <View style={{justifyContent: 'center'}}>
                <TouchableHighlight
                    style={{
                        backgroundColor: item.isSelected ? Color.BLACK : Color.TEXT_SECONDARY,
                        alignItems: 'center',
                        justifyContent: 'center',
                        height: 40,
                        width: 40,
                        borderRadius: 20
                    }}
                    onPress={this.onSelectWorker.bind(this, index, item)} underlayColor={Color.BLACK}>
                    <Icon name='done'
                          size={20}
                          color={Color.WHITE}/>
                </TouchableHighlight>
            </View>
        </View>
    );

};
onSelectWorker = (index, item) => {
    console.log("Selected index : ", index);
    let tempList = this.state.list;
    tempList[index].isSelected = tempList[index].isSelected ? false : true
    this.setState({
        list: tempList
    });

};
render() {
    return (
        <View style={styles.notification_Container}>
            <FlatList
                data={this.state.list}
                renderItem={
                    ({index, item}) => this.renderListItem(index, item)
                }
                keyExtractor={item => item.id}
                extraData={this.state}
            />
        </View>
    )
}




回答2:


You need to add a key to your ListItem which is based on a unique id of the item, so that React can distinguish between the items rendered.

When you use index of an array as a key, React will optimize and not render properly. What happens in such a scenario can be explained with an example.

Suppose React renders an array of 10 items and renders 10 components. Suppose the 5th item is then removed. On the next render React will receive an array of 9 items and so React will render 9 components. This will show up as the 10th component getting removed, instead of the 5th, because React has no way of differentiating between the items based on index.

Therefore always use a unique identifier as a key for components that are rendered from an array of items.



来源:https://stackoverflow.com/questions/46658124/checked-unchecked-doesnt-working-in-listview-react-native

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!