简体   繁体   中英

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?

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';

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

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
  })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM