'react-native-router-flux: How to return to previous Scene forcing reload of data?
I'm using a List View
class GroupList extends Component {
componentWillMount() {
this.props.fetchGroups();
I fetch from firebase a VERY SHORT list of elements.
export const fetchGroups = () => {
const { currentUser } = firebase.auth();
return (dispatch) => {
dispatch({
type: FETCHING_GROUPS
});
firebase.database().ref(`/users/${currentUser.uid}/groups`)
.on('value', snapshot => {
dispatch({
type: GROUPS_FETCHED,
payload: snapshot.val()
});
});
};
};
To create a new item I use the top-right Button offered from react-native-router-flux
<Scene
key="groupList"
component={GroupList}
title="Gruppi di servizio"
hideNavBar={false}
rightTitle="Nuovo"
onRight={() => Actions.groupForm({ formType: NEW_GROUP_FORM_TYPE })}
sceneStyle={{ paddingTop: 65 }}
/>
So I click top-right 'new' button and I see my form.
User then save the new group name
This is my action to Save to firebase:
return (dispatch) => {
dispatch({
type: TRYING_TO_CREATE_GROUP,
});
firebase.database().ref(`/users/${currentUser.uid}/groups`)
.push({ groupName })
.then(() => {
dispatch({ type: CREATE_GROUP_SUCCESS });
Actions.groupList({ type: 'reset' });
})
.catch((errorText) => {
dispatch({
type: CREATE_GROUP_FAILED,
payload: errorText
});
});
};
What's the problem?
After the first round of
Actions.groupForm({ formType: NEW_GROUP_FORM_TYPE })}
and
Actions.groupList({ type: 'reset' })
My GroupList is succesfully refreshed, because componentWillMount is called again.
The problem is that after the SECOND round of groupForm -> groupList my list is no more refreshed.
Adding a console log to componentWillMount I noticed that it's no more executed.
Why?
What's the right way to return to the Scene 'groupList' , forcing the refresh at any cost?
Solution 1:[1]
I haven't worked with react-native-router-flux but I've run into the same problem and hopefully can give you enough to figure out how to do it with that library.
Basically It doesn't get called again (componentWillMount) because the component is already mounted and its just returning focus to that component. What you have to do is pass that fetchGroups()
to wherever the next scene is and call it again once you're returning back to the GroupList scene which will cause a re-render with the most updated information. Let me know if I should clarify further.
Solution 2:[2]
I solved this by doing the following
Actions.replace(sceneKey, props );
For your code
Actions.replace('groupForm', { formType: NEW_GROUP_FORM_TYPE } );
Hope this help!
Solution 3:[3]
This has worked for me. Try it. The gist of it is when you define a Scene, you can override its "onBack" function. In order to force refresh of the previous page, you have to provide it with a prop with a different value each time, thus the Math.random().
<Scene
key='title'
component={YourComponent}
title='Title'
onBack={() => Actions.pop({ refresh: Math.random() })}
/>
Solution 4:[4]
Inspired by @Matt's solution, I solved my problem. And I am gonna post my sample code.
The idea is that if you wanna refresh the parent page while routing back from a child page, the way I do it is to pass a destroy and an update callback function to the child. The destroy function makes sure that the page falls back to its initial state, while the update function will fetch the latest data.
// parent scene
Actions.childSceneName({
onBack: () => this.props.fetchData(),
destroyParent: () => this.props.destroyPage(),
})
So that the child page can invoke the functions before routing back.
// child scene
componentWillUnmount() {
this.props.destroyParent()
this.props.onBack()
}
Solution 5:[5]
The best way is using a State Manager OR the new Context API of React.
This is the flow:
- Entering into ScreenOne
- From ScreenOne open ScreenTwo (both using state management)
- When finishing all the actions in ScreenTwo, call your function that reloads ScreenOne, at the same time use Actions.pop() to leave current screen (leaving ScreenTwo, and getting back into ScreenOne).
- Done! your ScreenOne is reloaded with new data.
Summary: The key of this is calling your function that reloads Previous Screen.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Matt Aft |
Solution 2 | Kumar |
Solution 3 | Jingjie Zhan |
Solution 4 | Wenyu Luo |
Solution 5 | NingaCodingTRV |