FlatList在状态改变时没有重新渲染。

4
按下按钮(ButtonComponent)后,按钮的状态会改变。现在我将该状态传递给<FlatList>中的<FlatListItem>(一个子组件)。根据该状态,<FlatList>中的每个项目都应重新排列。
我刚刚了解到这个extraData属性,但不确定如何在代码中使用它。
这不是什么新鲜事,而是像简单的复选框实现。 一切都运行良好,但当我按下“全选”按钮时,所有剩余的选择按钮没有被切换为选定状态。

image-1

image-2

class FlatListItem extends Component{  
  constructor(props){
    super(props)
    const{ isSelected }=this.props
    this.state={
        selectedStatus:isSelected,
    }
}

changeSelectStatus=(key)=>{
    this.setState({selectedStatus:!this.state.selectedStatus});
    return key;
}

render(){
    return(
        <View style={{flex:1,
            flexDirection:'row',
            backgroundColor:'white'}}>
            <View>
                <Image
                    source={{uri:this.props.item.imageUri}}
                    style={{width:50, height:50, margin:5}}>
                </Image>
            </View>
            <View>
                <Text style={{color:'black', padding:10, fontSize:16}}>{this.props.item.name}</Text>
            </View>
            <View style={{flex:1, alignItems:'flex-end', paddingRight:-10}}>
                {this.state.selectedStatus?
                    **<ButtonComponent buttonColor={"black"} buttonTextColor={"white"} fullRounded={true}
                    borderHighlight={true} buttonWidth={70} buttonHeight={30} 
                    onPress={()=>this.props.showSelected(this.changeSelectStatus(this.props.item.key)) }>
                        Selected
                    </ButtonComponent>
                :
                    <ButtonComponent buttonColor={"white"} buttonTextColor={"black"} fullRounded={true}
                    borderHighlight={true} buttonWidth={70} buttonHeight={30} 
                    onPress={()=>this.props.showSelected(this.changeSelectStatus(this.props.item.key)) }>
                        Select
                    </ButtonComponent>
                }                    
            </View>
        </View>
    )
 }

  }
export default class SelectMembersBody extends Component {
constructor(props){
    super(props)
    this.state={
        selectedButtons:[],
        selectAllBtnStatus:false,
    }
}
selectAllMembers=()=>{
    let allMembers=[];
    if(!this.state.selectAllBtnStatus){
        membersData.forEach(element => {
            if(!this.state.selectedButtons.includes(element.key))
                allMembers.push(element.key)                
        });
        this.setState({
            selectAllBtnStatus:!this.state.selectAllBtnStatus,
            selectedButtons:[...this.state.selectedButtons, allMembers]
        })
    }
    else{
        this.setState({
            selectAllBtnStatus:!this.state.selectAllBtnStatus,
            selectedButtons:[...allMembers]
        })
    }
}
showSelected=(callback)=>{
    let val = callback;
    if(!this.state.selectedButtons.includes(val))
        this.setState({selectedButtons:[...this.state.selectedButtons, val]});
    else{
        let newMarkers=[...this.state.selectedButtons]
        let index = newMarkers.indexOf(val);
        if (index >= 0) {
            newMarkers.splice( index, 1 );
        }
        this.setState({selectedButtons:newMarkers});
    }
}
render(){
    return(
        <View style={{flex:1, }}>
            <Text>{this.state.selectedButtons}</Text>
            <View>
                {this.state.selectAllBtnStatus?
                    <ButtonComponent buttonColor={"black"} buttonTextColor={"white"} fullRounded={true}
                        borderHighlight={true} buttonWidth={85} buttonHeight={30} onPress={this.selectAllMembers}>
                            Selected All
                    </ButtonComponent> 
                :
                    <ButtonComponent buttonColor={"white"} buttonTextColor={"black"} fullRounded={true}
                        borderHighlight={true} buttonWidth={85} buttonHeight={30} onPress={this.selectAllMembers}>
                            Select All
                    </ButtonComponent> }
            </View>                
            <FlatList data={membersData} extraData={this.state}
                renderItem={({item, index})=>{
                    return(
                        <View>
                            <FlatListItem item={item} index={index} isSelected={this.state.selectAllBtnStatus} showSelected={this.showSelected} ></FlatListItem>
                        </View>
                    )
                }
            }></FlatList>       
        </View>
    )
  }
}

展示一下selectAllMembers函数内部的内容。 - Jojo Narte
重新排列FlatList成什么样? - Afaq Ahmed Khan
@JojoNarte 请现在查看我的完整代码。 - Charanrajh Pepakayala
@Afaq,我的每个FlatList项中都有一个按钮。根据父组件中的此按钮组件状态,子组件(FlatListItem)中的按钮状态会发生变化。 - Charanrajh Pepakayala
1个回答

2
我知道踏入别人的鞋子可能会更难。我在问题中提供的代码可能并不那么有效,因为我是一个学习者。这就是为什么进入代码流程会感到不舒服。因此,在阅读了一些文章、文档和类似的StackOverFlow问题后,我决定回答自己的问题。
我的问题是为什么在setState时flatlist没有重新渲染。更准确地说,如果您已经浏览了上面的图片,选择“全选”按钮后,所有项目中的按钮都应该切换到选定状态。
为了使flatlist重新渲染,我们需要添加一个额外的属性"extraData" 通过将extraData={this.state}传递给FlatList,我们确保FlatList本身在state.selected更改时重新渲染。如果不设置此属性,FlatList将不知道它需要重新渲染任何项目,因为它也是一个PureComponent,prop比较将不会显示任何更改。
您可以在这里获取完整的文档
在我的情况下,我设置了 extraData = {this.state},因为 flatlist 每个项目中的按钮状态都取决于父组件中存在的数组。 因此,我通过 props 将其发送到子组件。
现在,flatlist 运行良好,并在每次状态更新时重新渲染。

谢谢,伙计。你帮我们省了不少时间。 - Anukul Rawat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接