React Native Change Page after 5 seconds - react-native

I'm newbie in react native and I don't know how to change page after 5 seconds.
I create an android.index.js file that will navigate to LandingPage.js. What I want to do is, when the LandingPage being loaded, it will wait for 5 seconds and then redirect / navigate to another page.
index.android.js
export default class DefaultProject extends Component {
render() {
return (
<Navigator
renderScene={(route, navigator) =>
<LandingPage/>
}
/>
)
LandingPage.js
export default class LandingPage extends Component {
render() {
return (
<Image source={require('./images/event3.jpeg')}
style={styles.container} />
//How to redirect to another page from here after 5 secs?
);
}
}

You can use a simple setTimeout, as you would in a standard JS setup:
export default class LandingPage extends Component {
componentDidMount(){
// Start counting when the page is loaded
this.timeoutHandle = setTimeout(()=>{
// Add your logic for the transition
}, 5000);
}
componentWillUnmount(){
clearTimeout(this.timeoutHandle); // This is just necessary in the case that the screen is closed before the timeout fires, otherwise it would cause a memory leak that would trigger the transition regardless, breaking the user experience.
}
render() {
return (
<Image source={require('./images/event3.jpeg')}
style={styles.container} />
//How to redirect to another page from here after 5 secs?
);
}
}

I'm using lodash for this:
export default class Splash extends React.Component {
constructor(props) {
super(props);
}
async componentWillMount() {
_.delay(() => this.props.navigator.replace({ component: 'login' }), 1000);
}
render() {
return (
...
);
}
}
This will only work if you have a Navigator set up. Check this article:
React Native Navigator — Navigating Like A Pro in React Native

Related

SpashScreen React Native

So Im trying to create a splash screen for my react native app on android and I'm running into a problem where it seems its not able to SpashScreen.hide() due to my aws-amplify withAuthenticator. It just constantly stays on the splash screen
const AppContainer = createAppContainer(App);
class RealApp extends React.Component {
componentDidMount() {
SplashScreen.hide();
}
constructor(props) {
super(props);
}
render() {
return(
<AppContainer></AppContainer>
);
}
}
export default withAuthenticator(RealApp, {
signUpConfig,
usernameAttributes
});
With this it constantly stays on the SplashScreen Image. I then changed it around a little and got rid of the 'WithAuthenticator' like so:
const AppContainer = createAppContainer(App);
export default class RealApp extends React.Component {
componentDidMount() {
SplashScreen.hide();
}
constructor(props) {
super(props);
}
render() {
return(
<AppContainer></AppContainer>
);
}
}
That sort of worked in the sense it showed the SplashScreen then my Amplify Login Page but had the bottom Navbar already rendered with the Login page so could switch to different pages just the amplify login UI was still on the home page etc.
Instead of hide splash screen just navigate your self to another screen with setTimeout function
componentDidMount() {
globalAny.isEditable = true;
if (Constant.isIosDevice()) {
if (CommonTask != undefined) {
CommonTask.getStatusHeight((error: any, events: any) => {
// console.log(events);
Constant.setStatusHeight({
top: events.top,
bottom: events.bottom
});
});
}
} else {
Constant.setStatusHeight({
top: StatusBar.currentHeight,
bottom: 0
});
}
// AsyncStorage.setItem("defaultUserData","0");
setTimeout(() => {
this._token();
}, 3000);
}

How to change react native app layout from api

I have developed an store app, my boss wants a feature that from wordpress panel select predefined layout to change the whole design and choose which category to be first or .... .
I have created all designs and components that needed, but I do not know how to change app layout that I recieved from api, is there any code or help for that. This change is not about color , its about changing whole home page app layout
Sorry for my english
Here is a simple example that you could implement.
You'll need to create custom complete components for each layout for the homepage.
Then you'll need to call the Wordpress API to get the layout name that needs to be displayed.
import React, { PureComponent } from 'react';
import { AppRegistry } from 'react-native';
import Layout1 from './components/Home/Layout1';
import Layout2 from './components/Home/Layout2';
import Layout3 from './components/Home/Layout3';
import Layout4 from './components/Home/Layout4';
import Loading from './components/Loading';
class HomePage extends PureComponent {
constructor(props) {
super(props);
this.state = {
layout: null
};
}
async componentDidMount() {
const response = await fetch('https://example.com/wp-json/whatever-api-endpoint')
.then(r => r.json());
this.setState({
layout: response
});
}
getContentElement = () => {
switch (this.state.layout) {
case 'layout_1': return <Layout1 />;
case 'layout_2': return <Layout2 />;
case 'layout_3': return <Layout3 />;
case 'layout_4': return <Layout4 />;
default: return <Loading />
}
};
render() {
const contentElement = this.getContentElement();
return (
<View>
{contentElement}
</View>
);
}
}
AppRegistry.registerComponent('MyApp', () => HomePage);

Navigation.goBack() with an API call in React-Native

In my application, I have few cases where navigation.goBack() cannot be used. I use react-navigation for navigation. When i'm in the detail screen, When I go back, I want to send an API call to get the latest records to the parent screen. So I used, navigation.navigate() instead of navigation.goBack(); But, this makes my app slow if I navigate and navigate back few times. It gets very slow if I do this few more times. What is the reason behind this? How the navigation.navigate() differs from navigation.goBack()?
What is the preferred way of handling this kind of scenario?
is there a way to pass param from navigate.goback() and parent can listen to the params and update its state?
You can pass a callback function as parameter (as mentioned in other answers).
Here is a more clear example, when you navigate from A to B and you want B to communicate information back to A you can pass a callback (here onSelect):
ViewA.js
import React from "react";
import { Button, Text, View } from "react-native";
class ViewA extends React.Component {
state = { selected: false };
onSelect = data => {
this.setState(data);
};
onPress = () => {
this.props.navigate("ViewB", { onSelect: this.onSelect });
};
render() {
return (
<View>
<Text>{this.state.selected ? "Selected" : "Not Selected"}</Text>
<Button title="Next" onPress={this.onPress} />
</View>
);
}
}
ViewB.js
import React from "react";
import { Button } from "react-native";
class ViewB extends React.Component {
goBack() {
const { navigation } = this.props;
navigation.goBack();
navigation.state.params.onSelect({ selected: true });
}
render() {
return <Button title="back" onPress={this.goBack} />;
}
}
Hats off for debrice - Refer to https://github.com/react-navigation/react-navigation/issues/288#issuecomment-315684617

How to implement jest unit test with react-navigation

I currently working on adding jest unit test for the react-navigation, for example:
My StackNavigator
const Nav = StackNavigator({
Home: {
screen: Home,
},
Second: {
screen: Second,
}
});
export default class App extends Component<{}> {
render() {
return (
<Nav/>
);
}
}
My Home component
export default class Home extends Component<{}> {
_goToNextPage = () => {
this.props.navigation.navigate('Second');
}
render() {
return (
<View>
<Text>Home</Text>
<Button
onPress={this._goToNextPage}
title="Go to Second Page"
>Click to next page</Button>
</View>
);
}
}
My Second component
export default class Second extends Component<{}> {
render() {
return (
<View>
<Text>Second</Text>
</View>
);
}
}
How should I write jest unit test to test "when I click the GoToNextPage button, and the Second Component should be rendered correctly ?"
I do not find any useful info about jest with react-navigation, Any help will be much appreciated!!!
Thanks a lot~
I personally like #testing-library/react for this because of their philosophy around testing from the user perspective. I'd imagine your test would look something like the following:
it('shows the second component when the next button is clicked', async () => {
// Renders your app
const { getByText, findByText } = render(<App />);
// Clicks your button
fireEvent.click(getByText('Click to next page'));
// Waits for the 'Second' text to be visible, could be async or sync, in this
// case I'm using the async expectation style
await wait(() => expect(getByText('Second')));
});
I would test this in a way that separates the concerns of the click of the button and the validation that it renders properly by simply rendering the second component and checking it against your snapshot.
// inside your second component test - still using testing-library
it('matches the snapshot', () => {
expect(render(<Second />).container).toMatchSnapshot();
});

React Native Redux store dispatches reducers correctly, but doesn't update UI component

Working on a cancer treatment app in react native:
Current functionality: when I move the sliders and change the date on my app, it dispatches changes to the redux store successfully. Unfortunately, my UI doesn't update, even though I am calling the same store from the presentational components that I called for dispatch.
That results in this:
GIF of redux store changing while UI is static
Printing via
store.getState();
store.subscribe(() =>
console.log(store.getState())
);
I tried using subscription, but it seems like this isn't the right way to go about this. Thoughts?
snippets from my code (all in one small file, linked below)
Action
//action
function set_num_treatments(num) {
return {
type: SET_NUM_TREATMENTS,
num: num
}
}
setting the title
SET_NUM_TREATMENTS = "SET_NUM_TREATMENTS"
main reducer
function main_reducer(state = initialState, action) {
switch (action.type) {
case SET_PAGE_VIEW:
return Object.assign({}, state, {
current_page: action.page_of_interest
})
case SET_NUM_TREATMENTS:
return Object.assign({}, state, {
num_treatments: action.num
})
case SET_INTER_TREATMENT_INTERVAL:
return Object.assign({}, state, {
inter_treatment_interval: action.weeks_between_treatments
})
case SET_TREATMENT_START_DATE:
return Object.assign({}, state, {
treatment_start_date: action.date
})
default:
return state
}
return state
}
Here's where I start the store & produce the printing functionality
let store = createStore(main_reducer);
store.getState();
store.subscribe(() =>
console.log(store.getState())
);
here's the presentational components
class TreatmentSettings extends React.Component {
constructor(props){
super(props)
}
render() {
const props = this.props
const {store} = props
const state = store.getState()
return(
<View style={styles.treatment_option_slider_card}>
<Text style={styles.my_font, styles.tx_settings_header}>{state.num_treatments} Treatments</Text>
<Slider step={1} minimumValue={1} maximumValue={20} value={12}
onValueChange={(num_treatments) => {store.dispatch(set_num_treatments(num_treatments))}} />
<Text style={styles.my_font, styles.tx_settings_header}>X Weeks Between Treatments</Text>
<Slider step={1} minimumValue={1} maximumValue={4} value={2} style={{marginBottom:60}}
onValueChange={(value) => {store.dispatch(set_inter_treatment_interval(value))}}
/>
</View>
)
}
}
These final two components hold the main containers for the app
export default class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Provider store={createStore(main_reducer)}>
<AppContainer />
</Provider>
);
}
}
class AppContainer extends React.Component {
constructor(props){
super(props)
}
render(){
return(
<View style={styles.container}>
<TreatmentSettings store={store} />
<Text>footertext</Text>
</View>
)
}
}
the one gist file is here if you want to see it all: https://github.com/briancohn/learning-redux/blob/navigation_addn/App.js
I really appreciate the help—
Thanks in advance!
-Brian
I think the way you are updating the store is fine but there’s something wrong with how your components are listening to the changes.
It seems you meant to use connect from react-redux for the containers to connect to the store. Then you can use mapStateToProps to get the data from the store to pass into the components as props. Check https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options for example.