Search code examples
react-nativerefreshrender

How to refresh/re-render flatlist on react-native?


im trying to refresh my flatlist from some page without going back to the principal menu, but it doesnt work.

I've already readed about extraData, but it doesnt work either.

Basiclly my program is like that: I have a page called "passwords" and i add some passwords there from another page called "add passwords". When i click to add a password, i want to refresh the flatlist from the page "passwords" to show me the password that i just added.

This is my code from the page "add passwords"

...

state = {
arr: [],
local: '',
password: '',
obj: {
  local: '',
  password: ''
},
count: 1,
texto: ''
};

componentDidMount() {
//Here is the Trick
const { navigation } = this.props;
//Adding an event listner om focus
//So whenever the screen will have focus it will set the state to zero
this.focusListener = navigation.addListener('didFocus', () => {
  this.setState({ count: 0 });
});
}

storeItem(item) {
try {
  //we want to wait for the Promise returned by AsyncStorage.setItem()
  //to be resolved to the actual value before returning the value~
  console.log(item)
  var joined = this.state.arr.concat(item);
  console.log(joined)

  this.setState({ arr: joined })

  AsyncStorage.setItem('array', JSON.stringify(joined));
  console.log(this.state.arr)

} catch (error) {
  console.log(error.message);
}
}

 componentWillMount() {
 AsyncStorage.getItem('array').then(array => {
  item = JSON.parse(array)
  array ? this.setState({ arr: item }) : null;
  console.log(item)


})
}



render() {

return (

  <View style={styles.container}>
    <TextInput
      style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
      onChangeText={(text) => this.setState({ local: text })}
      value={this.state.local}
    />

    <TextInput
      secureTextEntry={true}
      style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
      onChangeText={(text) => this.setState({ password: text })}
      value={this.state.password}
    />


    <Button title='Adicionar'
      onPress={() => this.storeItem({ local: this.state.local, password: this.state.password }) + alert("Adicionado com sucesso!") + this.props.navigation.navigate('Passwords')}      
    ></Button>

  </View>

);
}
}

And this is my page "passwords" where i want to refresh

componentWillMount() {
const { navigation } = this.props;
this.willFocusListener = navigation.addListener(
  'willFocus',
  () => {
    this.setState({ count: 10 })
  }
)

AsyncStorage.getItem('array').then(array => {
  item = JSON.parse(array)

  item ? this.setState({ arr: item }) : null;
  console.log(this.state.arr)
})

}

 renderItem = ({ item }) => (
<View style={{ flexDirection: 'row' }} style={styles.passwordContainer}>
  <Text> {item.local} </Text>
  <Text> {item.password} </Text>
</View>

)

render() {
return (
  <View style={styles.container}>
    <FlatList
      data={this.state.arr}
      renderItem={this.renderItem}
      extraData={this.state} //this is what i tryied
    />
  </View>
);

Solution

  • You can use your listener to update the state.

    componentWillMount() {
      this.willFocusListener = navigation.addListener(
       'willFocus',
       () => this.updateData()
    }
    
    updateData = () =>  {
      this.setState({ count: 10 });
      AsyncStorage.getItem('array').then(array => {
        item = JSON.parse(array)
        item ? this.setState({ arr: item }) : null;
        console.log(this.state.arr)
      });
    }