How to implement a callback through a component - react-native

Basically, i click that stack other page when its open, and i want to implement a callback to update the page if a specific button is pressed inside this second page. My problem is, the button that navigate to the second page is inside a component that is rendering on the first page, like this:
Home page
<FlatList
style={styles.listView}
contentContainerStyle={styles.listContentView}
data={availableJobs}
keyExtractor={service => service.id.toString()}
renderItem={({item}) => <CompleteCalls style={styles.listItem} job={item}/>}
showsHorizontalScrollIndicator={false}
ListEmptyComponent={<MyEmpty />}
horizontal
/>
And the CompleteCalls i had the button to navigate to the second page:
<TouchableOpacity
style={styles.buttonContainer}
onPress={() => Navigator.navigate('ServiceDetails', {job} )}>
<MyText style={styles.button}>Resumo</MyText>
<MyIcon style={styles.resumeIcon}>{Icons.CHEVRON_RIGHT}</MyIcon>
</TouchableOpacity>
So basically, i'm calling the ServiceDetails page inside the CompleteCalls component, through the Home page.
Inside the ServiceDetails i render another component, that is a button, to execute a function.
<ActionButton job={job}/>
This ActionButton just render a button and had a function.
Inside the ServiceDetails i can return direct to the Home page.
How can i pass a callback through all this just when i click on the ActionButton? I need to update the Home page when i got back after clicking the button, but not when i go to another pages, so a Listener is annoying, since its reload the page after every interaction.

Related

Update and reload component in react native

I am trying to refresh/ reload the page with an updated document once I click on a button. saveAnnotations(); saves the changes made to the document on the device and also updates the document with any other updates from other devices in the database.
The filepath is a REST URL to get the document.
After I click the sync button, the edits made to the document are saved but I want to reload the page so that it pulls the latest updated document from the database in the onclick button itself.
When I go back and return on this page I am able to see the lastest changes made but I want the document to reload when I click on sync button.
I tried using window.location.reload(false); but it closes the page where as I just want to reload the page or rerender filepath props to pull latest changes when I click on the sync button.
Any suggestions on how do I achieve that?
here's my code snippet
reRender = () => {
// calling the forceUpdate() method
this.forceUpdate();
window.location.reload(false);
};
render() {
return (
<View style={{ flex: 1 }}>
<DocumentView
document={filepath}
/>
<View style={styles.button}>
<Button
onPress={() => {
// Save Document
this.saveAnnotations();
}}
title="Sync"
/>
</View>
</View>
</View>
);
}
To achieve what you are looking for, you need to trigger the render method. Doing this will show the updated document. Here is a diagram showing the lifecycle methods of React components. As you can see, there are three ways to trigger the render method:
The component receives new props
Calling setState
Calling forceUpdate
For your use case, I would suggest adding a call to forceUpdate, like so:
<View style={styles.button}>
<Button
onPress={() => {
// Save Document
this.saveAnnotations();
this.forceUpdate(); // <-- add this
}}
title="Sync"
/>
</View>

How to show Modal to user before changing routes in React Navigation

So I'm wondering if I'm just not using the right vocabulary in my search - but what I thought might be cool for an app I'm working on would be:
A user starts editing their post.
In case they go back or press a tab to go to another page before
they press "Update".
The screen change is intercepted and a modal shows up and asks if
they want to keep their changes.
I know you can add event handlers - https://reactnavigation.org/docs/navigation-events/ but I'm not sure if these are what I need, I've tested and the prevent default didn't seem to do what I thought it would. That and I couldn't find a way to find what the next intended route that the app would need to go to once they have said "Dismiss" on the modal.
Could anyone point me in the right direction please?
you can create your own modal and back button so you can control what each item do
this.state={
modalConfirm: false
}
goBack = () => { //your goback function }
cancel = () => { this.setState ({modalConfirm :false})
<View>
<TouchableOpacity onPress={()=> this.setState({modalConfirm: true})>
<Icon name='arrow-left' />
</TouchableOpacity>
<Modal visible={this.state.modalConfirm}>
<Text>Do you want to go back? </Text>
<Button title='Go back' onPress={this.goBack} />
<Button title='No' onPress={this.cancel} />
</Modal>
<View>
//your content
</View>
</View>

How to persist stacked screens when switching between tabs in React Native Navigation

I am using a bottom tab navigator created with createBottomTabNavigator() and passing it several screens, each of which contain their own stack navigation:
const tabNavigator = createBottomTabNavigator({
TradingStack,
LendingStack,
FinanceStack,
AccountBalancesStack,
OtherStack,
},
{
tabBarComponent: props => (
<NavigationFooter />
)
}
);
I am passing it my own custom bottom navigator component called <NavigationFooter />. When tabBarComponent is omitted, a built-in bottom tab navigator is used, however I need more functionality than this built-in solution offers. The issue is, when using my custom tab bar, I lose stack persistence in the individual screens. To clarify, let's say my TradingStack screen has several screens that stack on top of it, and I open one of those. When using the default tab bar, if I switch to the LendingStack screen and then back to TradingStack, I will still be on the stacked screen that was pushed on top of the root TradingStack screen.
However, when using my custom tab bar component, moving between these tabs/screens will always bring me to the root of each one instead of bringing me back to the stacked screen that the tab was on before switching away from it. Here's my custom Footer component:
function Footer({navigation}) {
return(
<View style={styles.tabBarStyle}>
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('Trading')} />
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('Lending')} />
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('Finance')} />
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('AccountBalances')} />
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('TabScreen')} />
</View>
);
}
const NavigationFooter = withNavigation(Footer);
As you can see, when one of the TouchableOpacity elements is pressed, I use navigation.navigate() to go to the desired screen, but, as mentioned, this brings me to the root of the screen. I understand that this is basically explicitly telling the app to navigate to a root screen of a tab, but I don't know how to make the tab "remember" the stacked screen it was on before I move away, as is the behavior of the default tab bar.
You can pass the name of the actual stack to navigation.navigate instead of the name of the starting screen on that specific tab, and the stacked screens should persist. So, instead of, for example
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('Trading')}/> //name of the screen
you should pass it
<TouchableOpacity style={styles.tabStyle} onPress={() => navigation.navigate('TradingStack')}/> //name of the stack
assuming Trading is the starting screen within the TradingStack.

get previous screen when click on go back button,

I created push notification expo.
when I receive a notification and click on it, I navigate to the screen that is called productDetail to display for example the product's detail A by the instuction:
navigation.push('detailProduct',{idProduct:notification.data.idProduct}).
the cause that lets me to use navigation.push is to use the function componentDidMount each time when I navigate to detailProduct screen, however navigation.navigate does not allow me.
and when I receive the notification of product B, I navigate to the
productDetail screen to display the detail of B.
so my problem is: when I click the return button I do not get the product detail A. Knowing I'm using redux to store the data.
How can I solve this problem or what is the best method that allows me to save the detail product A
for react-navigation
<TouchableOpacity onPress={()=>{ this.props.navigation.goback() }}>
<Text>Go Back</Text>
</TouchableOpacity>
for react-native-router-flux
<TouchableOpacity onPress={() => { Actions.pop() }}>
<Text>Go Back</Text>
</TouchableOpacity>

Changing components based on state

I'm working in react-native. I have a form page in my mobile app and have an edit button and back button. Once the edit button is clicked, I want a save and cancel button to replace the edit and back button, and they should have their own functionality. I have tried componentWillUpdate() and if else statements in my render function, but neither seem to work.
You can put all the buttons in your render function, controlled with state(eg. inEditMode). When user click on edit button you can set inEditMode to true and display the edit & back button.
Something like this:
render() {
this.state.inEditMode ?
<View>
<EditButton />
<BackButton />
</View> :
<View>
<CancelButton />
<SaveButton />
</View>
}