FlatList не выполняет повторный рендеринг при изменении состояния - PullRequest
0 голосов
/ 20 февраля 2019

При нажатии кнопки (ButtonComponent) состояние кнопки изменяется.Теперь я передаю это состояние <FlatListItem> (дочернему компоненту) внутри <FlatList>.В зависимости от этого статуса каждый элемент в <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>
    )
  }
}

1 Ответ

0 голосов
/ 21 февраля 2019

Я знаю, что труднее войти в чужую обувь.Код, который я привел в своем вопросе, может быть не таким эффективным, так как я учусь.Вот почему неудобно переходить к потоку кода.Поэтому я решил ответить на свой вопрос после прочтения некоторых статей, документов и подобных вопросов на StackOverFlow.

Итак, мой вопрос - почему плоский список не перерисовывается на setState.Если быть более точным, если вы просмотрели изображения выше, при выборе кнопки «Выбрать все» все кнопки в элементах должны быть переключены в выбранное состояние.

Чтобы повторно отобразить плоский список, нам нужночтобы добавить дополнительный пропеллер "extraData"

Передав extraData = {this.state} в FlatList, мы гарантируем, что FlatList будет заново визуализироваться при изменении state.selected.Без установки этого реквизита FlatList не знал бы, что ему необходимо повторно визуализировать какие-либо элементы, поскольку он также является PureComponent, и сравнение реквизитов не покажет никаких изменений.

Вы можете получить его полностью документация здесь .

В моем случае я установил extraData = {this.state}, поскольку состояние кнопок в каждом элементе flatlist зависит от массива, присутствующего в родительском компоненте.Итак, я отправил его дочернему компоненту через реквизит.

Теперь плоский список работает нормально и выполняет рендеринг при каждом обновлении состояния.

...