Ao contrário de ListView, podemos atualizar this.state.datasource. Existe algum método ou exemplo para atualizar FlatList ou renderizá-lo novamente?
Meu objetivo é atualizar o valor do texto quando o usuário pressiona o botão ...
renderEntries({ item, index }) {
return(
<TouchableHighlight onPress={()=> this.setState({value: this.state.data[index].value+1})>
<Text>{this.state.data[index].value}</Text>
</TouchableHighlight>
)
}
<FlatList
ref={(ref) => { this.list = ref; }}
keyExtractor={(item) => item.entry.entryId}
data={this.state.data}
renderItem={this.renderEntries.bind(this)}
horizontal={false} />
reactjs
react-native
react-native-flatlist
Shalonteoh
fonte
fonte
PureComponent
que significa que não será renderizado novamente se os adereços permanecerem rasos. Certifique-se de que tudo de que suarenderItem
função depende seja passado como um acessório que não está===
após atualizações, caso contrário, sua IU pode não ser atualizada nas alterações. Isso inclui odata
estado do componente principal e prop. " Você está seguindo este conselho?extraData
eshouldItemUpdate
não consegui fazer a lista para renderizar novamente. O que acabei fazendo foi limpar o estado, aguardar que isso fosse renderizado e depois atualizar o estado.this.setState({ data: null }, () => { this.setState({ data: actualData }) });
Respostas:
Use a
extraData
propriedade em seu componente FlatList.Conforme afirma a documentação:
fonte
data={this.props.searchBookResults}
e nemextraData={this.state}
nemextraData={this.props}
está funcionando para mim. Edata={this.props.searchBookResults}
não está funcionando também. O que fazer ?... data={this.props.searchBookResults} extraData={this.state.refresh} onPress={()={this.setState({ refresh: !refresh})}
extraData
, o componente não atualiza :(extraData
prop sejam alterados quando os itens filhos precisarem ser renderizados novamente. Por exemplo, se os itens da lista podem estar ativos / inativos, certifique-se de que a variável de status, seja parte dothis.state
objeto outhis.props
objeto, é o que deve entrarextraData
. Pode ser um cursor ou uma matriz de itens ativos, etc.shouldComponentUpdate()
, assim que atualizei ou comentei completamente, as coisas estavam funcionando exatamente como descrito na documentação.Para uma solução rápida e simples, experimente:
defina dados extras para um valor booleano.
extraData = {this.state.refresh}
Alterne o valor do estado booleano quando você quiser renderizar novamente / atualizar a lista
this.setState({ refresh: !this.state.refresh })
fonte
this.data.refresh()
. Em vez disso, definimos um booleano e o alteramos. O valor booleano em si não tem significado, então qual é o objetivo dele existir? ... (Não há nenhum ponto, além de fazer a atualização de dados correta?)this.state.users
não estava funcionando, embora eu tenha mudado um sinalizador em alguns usuários.Oh, isso é fácil, basta usar
extraData
Você vê a maneira como os dados extras funcionam nos bastidores: a FlatList ou a VirtualisedList apenas verifica se o objeto foi alterado por meio de um
onComponentWillReceiveProps
método normal .Portanto, tudo o que você precisa fazer é certificar-se de fornecer algo que mude ao
extraData
.Aqui está o que eu faço:
Estou usando o immutable.js, então tudo que faço é passar um Mapa (objeto imutável) que contém tudo o que desejo assistir.
<FlatList data={this.state.calendarMonths} extraData={Map({ foo: this.props.foo, bar: this.props.bar })} renderItem={({ item })=>(( <CustomComponentRow item={item} foo={this.props.foo} bar={this.props.bar} /> ))} />
Dessa forma, quando
this.props.foo
outhis.props.bar
mudar, nossoCustomComponentRow
será atualizado, pois o objeto imutável será um diferente do anterior.fonte
extraData
! obrigado pelo link para oVirtualisedList
código!OK. Acabei de descobrir que, se quisermos que a FlatList conheça a alteração dos dados fora da propriedade de dados, precisamos defini-la como extraData, então faço assim agora:
<FlatList data={...} extraData={this.state} .../>
consulte: https://facebook.github.io/react-native/docs/flatlist#extradata
fonte
Se você vai ter um botão, pode atualizar os dados com um setState dentro do onPress. SetState irá então renderizar novamente sua FlatList.
fonte
Depois de muito pesquisar e procurar por uma resposta real, finalmente consegui a resposta que acho que é a melhor:
<FlatList data={this.state.data} renderItem={this.renderItem} ListHeaderComponent={this.renderHeader} ListFooterComponent={this.renderFooter} ItemSeparatorComponent={this.renderSeparator} refreshing={this.state.refreshing} onRefresh={this.handleRefresh} onEndReached={this.handleLoadMore} onEndReachedThreshold={1} extraData={this.state.data} removeClippedSubviews={true} **keyExtractor={ (item, index) => index }** /> .....
meu principal problema era (KeyExtractor) eu não o estava usando assim. não funciona: keyExtractor = {(item) => item.ID} depois que mudei para isso, funcionou perfeitamente, espero que ajude alguém.
fonte
this.state.refreshing
e funçãohandleRefresh
?Resolvi este problema adicionando
extraData={this.state}
Verifique o código abaixo para obter mais detalhesrender() { return ( <View style={styles.container}> <FlatList data={this.state.arr} extraData={this.state} renderItem={({ item }) => <Text style={styles.item}>{item}</Text>} /> </View> ); }
fonte
Apenas uma extensão das respostas anteriores aqui. Duas partes para garantir, certifique-se de adicionar extraData e que seu keyExtractor é exclusivo. Se seu keyExtractor for constante, um re-renderizador não será acionado.
<FlatList data={this.state.AllArray} extraData={this.state.refresh} renderItem={({ item,index })=>this.renderPhoto(item,index)} keyExtractor={item => item.id} > </FlatList>
fonte
Eu substituí
FlatList
porSectionList
e é atualizado corretamente na mudança de estado.<SectionList keyExtractor={(item) => item.entry.entryId} sections={section} renderItem={this.renderEntries.bind(this)} renderSectionHeader={() => null} />
A única coisa que você precisa ter em mente é que
section
tem uma estrutura diferente:const section = [{ id: 0, data: this.state.data, }]
fonte
Para mim, o truque era extraData e aprofundar no componente do item mais uma vez
state = { uniqueValue: 0 } <FlatList keyExtractor={(item, index) => item + index} data={this.props.photos} renderItem={this.renderItem} ItemSeparatorComponent={this.renderSeparator} /> renderItem = (item) => { if(item.item.selected) { return ( <Button onPress={this.itemPressed.bind(this, item)}>Selected</Button> ); } return ( <Button onPress={this.itemPressed.bind(this, item)}>Not selected</Button>); } itemPressed (item) { this.props.photos.map((img, i) => { if(i === item.index) { if(img['selected') { delete img.selected; } else { img['selected'] = true; } this.setState({ uniqueValue: this.state.uniqueValue +1 }); } } }
fonte
Coloque variáveis que serão alteradas por sua interação em
extraData
Você pode ser criativo.
Por exemplo, se você estiver lidando com uma lista de alteração com caixas de seleção.
<FlatList data={this.state.data.items} extraData={this.state.data.items.length * (this.state.data.done.length + 1) } renderItem={({item}) => <View>
fonte
Se quisermos que a FlatList saiba que os dados mudam tanto prop quanto estado , podemos construir um objeto referenciando ambos prop e state e atualizar a flatlist.
const hasPropOrStateChange = { propKeyToWatch: this.props, ...this.state}; <FlatList data={...} extraData={this.hasPropOrStateChange} .../>
Documentos: https://facebook.github.io/react-native/docs/flatlist#extradata
fonte
Em react-native-flatlist, eles são uma propriedade chamada extraData. adicione a linha abaixo à sua lista plana.
<FlatList data={data } style={FlatListstyles} extraData={this.state} renderItem={this._renderItem} />
fonte
Neste exemplo, para forçar uma nova renderização, basta alterar a variável
machine
const [selected, setSelected] = useState(machine) useEffect(() => { setSelected(machine) }, [machine])
fonte
Apenas use:
onRefresh={true}
dentro do seu
flatList
componente.fonte
refreshing
propO extraData do Flatlist não estava funcionando para mim e por acaso eu estava usando um prop do redux. Isso soou semelhante aos problemas dos comentários na resposta do ED209. Acabei chamando setState manualmente quando recebo a proposta.
componentWillReceiveProps(nextProps: StateProps) { if (this.props.yourProp != null && nextProps.yourProp) { this.setState({ yourState: processProp(nextProps.yourProp) }); } } <FlatList data={this.state.yourState} extraData={this.state.yourState} />
Para aqueles que usam> React 17, use getDerivedStateFromProps
fonte