Flama
Flama

Reputation: 868

Triggering refresh on function component with navigate (React Native)

One of my screens in my app is a function component which looks like this:

export default function DonationsScreen({ navigation }) {
  const [requests, setRequests] = useState("")

  useEffect(() => {
    if (!requests) {
      getRequests()
    }
  }, [])

  // I omit some of the code here

  return (
    <SafeAreaView>
      <SearchBar lightTheme placeholder="Type Here..." />
      <FlatList
        data={requests}
        renderItem={({ item }) =>
          item.donationsLeft > 0 ? (
            <DonationItem request={item} navigation={navigation} />
          ) : null
        }
        keyExtractor={(item) => item.id}
      />
    </SafeAreaView>
  )
}

class DonationItem extends React.Component {
  render() {
    const { navigate } = this.props.navigation
    return (
      <Card title="hello">
        <Button
          buttonStyle={styles.donateButton}
          onPress={() =>
            this.props.navigation.push("Realizar donación", {
              request: this.props.request,
            })
          }
          title="Donar"
        />
      </Card>
    )
  }
}

So that onPress you see in DonationItem navigates to another screen called DonationFormScreen. What is in this screen doesn't really matter except that there is another navigate called in one of its methods:

this.props.navigation.push('Donación confirmada', {comingFrom: this.state.comingFrom});

And last, "Donación confirmada" is a screen DonationConfirmationScreen:

export default class DonationConfirmationScreen extends React.Component {

    render() {

        return(
        <View style={styles.confirmation}>
            <View style={styles.confirmationContent}>
                <Ionicons name='ios-checkmark-circle' color={'green'} size={130}/>
                <Button
                buttonStyle={styles.button}
                title='Listo' 
                onPress={() => this.props.navigation.navigate("Pedidos")}
                />
            </View>
        </View>
        );
    }
}

As you see this.props.navigation.navigate("Pedidos") is called inside the button and works fine. What I want to do is not only to navigate back to "Pedidos" (which is my DonationsScreen) but also trigger some sort of refresh, because I need getRequests() to be called again. How can I achieve this?

Upvotes: 2

Views: 1850

Answers (3)

Flama
Flama

Reputation: 868

Thanks to everyone who answered but I ended up using something else since I couldn't get the other things to work.

const isFocused = useIsFocused();

const [requests, setRequests] = useState('');

useEffect(() => {
  getRequests();
} , [isFocused])

As you see I ended up using isFocused. I had to add this import:

import { useIsFocused } from '@react-navigation/native';

Upvotes: 3

Denis Tsoi
Denis Tsoi

Reputation: 10424

Query request on mount

export default function DonationsScreen({ route, navigation }) {  
  const { getRequests } = route?.params

  useEffect(async () => {
    if (getRequests) {
      const req = await getRequests() 
      setRequests(req)
    }
  }, [])

perhaps passing dynamic getRequests as a route.param

onPress={() => { 
  this.props.navigation.push('Realizar donación', {
    request: this.props.request, 
    getRequests: getRequests
  })
}

Upvotes: 0

kareem adel
kareem adel

Reputation: 491

In your situation you could pass the method getRequests along with request, for example replace this line in DonationItem component :

onPress={() => this.props.navigation.push('Realizar donación', {request: this.props.request})}

With this line:

onPress={() => this.props.navigation.push('Realizar donación', {request: this.props.request, getRequests: getRequests})}

And keep passing it until you reach the target screen and then call the method getRequests once you're done.

Optional: consider using a state management library to avoid these issues such as this one: https://github.com/ctrlplusb/easy-peasy

Upvotes: 0

Related Questions