React Native pass state from a pure JS file - react-native

I have my react component on my main index file or my main component I would like to pass a state change to that component but from a pure JS file/function not sure what's the best approach or correct way of doing this. I have tested it with redux but feels like an overkill especially since I need to pass loading progress.
it's basically loading overlay which needs to be called from the post api file.
Here is my code
Index
render() {
return (
<View style={styles.container}>
<Provider store={store}>
<ConnectedRouter>
<Scene key="root" hideNavBar hideTabBar>
<Scene key="public">
<Scene key="login" component={Login} initial={true} title={'Login'} />
<Scene key="ResetPassword" component={ResetPassword} title={'Reset Password'} />
</Scene>
<Scene key="tabBar" tabs lazy>
<Scene key="tab1" title="Home" tabBarLabel="Home" icon={HomeTabIcon}>
<Scene key='Home' component={Home} title='Home' initial={true} panHandlers={null}/>
<Scene key='Teams' component={Teams} title='Teams' initial={false} />
</Scene>
<Scene key="tab2" title="Photos" tabBarLabel="Photos" icon={PhotosTabIcon}>
<Scene key='Photos' component={Photos} title='Photos' back backTitle='Back' initial={false} />
<Scene key='SinglePhoto' component={SinglePhoto} title='Photo' back backTitle='Back' initial={false} />
<Scene key='PhotoUpload' component={PhotoUpload} title='Upload Photo' back backTitle='Back' initial={false} />
</Scene>
<Scene key="tab3" title="Site Diary" tabBarLabel="Site Diary" icon={SiteDiaryTabIcon}>
<Scene key='SiteDiary' component={SiteDiary} title='SiteDiary' initial={false} />
</Scene>
</Scene>
</Scene>
</ConnectedRouter>
</Provider>
<MessageBar/>
<LoadingOverlay isVisible={this.state.overlayIsVisible} progress={this.state.overlayProgress} indeterminate={this.state.indeterminate} />
</View>
);
}
API file
export const sync = (isConnected) => {
const offlineData = store.getState().newData;
console.log(offlineData);
// We have offline data
if(!_.isEmpty(offlineData.photos)){
console.log('We have offline data')
// We have a connection
if(isConnected) {
console.log('We have a connection')
// Loops thur the offline data and uploads it
//for (let i = 0; i < offlineData.length; i++) {
//}
}
}
};
Which is getting called from index via the following
// Connection function for offline / online
_handleConnectionChange = (isConnected) => {
// Updates the store with selected project
store.dispatch(connectionActionCreators.update(isConnected));
// Gets the offline data from the store
const hasOfflineData = store.getState().newData.hasData;
console.log(hasOfflineData);
if(hasOfflineData){
this.setState({
overlayIsVisible:true,
//overlayProgress:0,
});
}
// Syncs data
syncOffineData.sync(isConnected);
};

Related

Cannot update during an existing state transition with react-native-router-flux

I need to show a modal using RNRF, but I get this warning (the modal is showing for a moment and then disapears with warning).
If I set the Scene's type prop to "replace" then everything works, but I can’t do Actions.pop() in that Scene (the last one)
const App = () => {
return (
<Provider store={store}>
<Router
backAndroidHandler={() => {
goBack();
return true;
}}
>
<Modal>
<Stack key="root" hideNavBar={true}>
<Scene
key={ROUTES.LOGIN}
type="push"
duration={1}
component={Login}
duration={1}
initial={true}
/>
<Scene
key={ROUTES.TRANSACTION_SUMMARY}
type="push"
duration={1}
component={TransactionSummary}
duration={1}
/>
<Scene
key={ROUTES.PHOTO_DIALOGUE}
type="push"
duration={1}
component={PhotoDialogue}
duration={1}
/>
</Stack>
<Scene modal key={ROUTES.ABOUT} type="push" component={About} hideNavBar />
</Modal>
</Router>
</Provider>
);
};
The last scene refers to the About component. It has a button with the onPress prop in the render method, there was a call goBack(). Works good without the brackets

React native router flux authentication flow for tabs as in show accounts tab in case of unauthorize and show profile tab in case of authorize

In my app, the authentication is not the first screen to be shown. The home page contains a list of item that a user can browse through and see the details of an individual item. In order, to subscribe to that item, I need to redirect the user to the accounts tab. In case user is logged in, I want to show the profile tab otherwise the login page which has is part of an auth stack of pages.
So how can I do that using react-native-router-flux, I have tried the following approach as per my understanding and it isn't working. I am new to react-native and struggling with this flow.
If there is another library which can help me to achieve this desired behavior, I would love to try it out.
Routing.tsx
<Router>
<Scene key="root" hideNavBar>
<Tabs key="tabbar" swipeEnabled tabBarStyle={styles.tabBar} showLabel={false} lazy>
<Scene key="homeTab" title="Home" iconName="ios-home" icon={TabIcon} hideNavBar>
<Scene key="home" component={Home} title="Home Page" initial />
<Scene key="details" component={ContentDetail} />
</Scene>
<Scene key="account" component={Splash} hideNavBar title="Profile" iconName="ios-person" icon={TabIcon}>
<Scene key="profileTab" title="Profile" iconName="ios-person" icon={TabIcon} hideNavBar>
<Scene key="profile" component={Profile} initial />
</Scene>
<Scene key="authTab" title="Account" iconName="ios-person" icon={TabIcon} hideNavBar>
<Scene key="login" component={Login} initial />
<Scene key="signup" component={Signup} />
<Scene key="verifyTac" component={VerifyTac} />
</Scene>
</Scene>
<Scene key="settingTab" title="Settings" iconName="ios-settings" icon={TabIcon} hideNavBar>
<Scene key="accInfo" component={AccountInfo} title="Account Info Page" initial />
</Scene>
</Tabs>
<Scene
key="search"
component={Search}
modal
hideNavBar
/>
</Scene>
</Router>
Splash.tsx
class Splash extends React.Component<Props, {}> {
constructor(props: Props) {
super(props);
}
componentDidMount() {
if (this.props.user && this.props.user.accessToken) Actions.replace('profileTab');
else Actions.replace('authTab');
}
render() {
console.log(' Splash props: ', this.props);
return <View></View>
}
}
const mapStateToProps = state => {
return {
user: state.authReducer
}
}
export default connect(mapStateToProps)(Splash);

React native router flux Reset Stack when change Tab

I word on react-native-router-flux and I have a problem ... I am reset my Stack navigation when I am changing of Tab navigation.
I try with backToInitial but I need to press two times on my tab for reset my stack ... I don't understand why.
My navigation :
-OSU
-Scarlet
-Gray
-VU
-Blue
-Black
So when I am on Blue and I press one time on OSU I when to access at Scarlet not gray
My code :
export default class App extends Component {
render() {
return (
<Router>
<Tabs
key="tabbar"
tabBarStyle={{ backgroundColor: '#FFFFFF' }}
backToInitial={true}
>
<Scene key="osu" title="OSU" icon={TabIcon} type='reset' backToInitial={true}>
<Scene
key="scarlet"
component={ScarletScreen}
title="Scarlet"
/>
<Scene
key="gray"
component={GrayScreen}
title="Gray"
/>
</Scene>
<Scene key="vu" title="VU" icon={TabIcon} backToInitial={true}>
<Scene
key="blue"
component={BlueScreen}
title="Blue"
/>
<Scene
key="black"
component={BlackScreen}
title="Black"
/>
</Scene>
</Tabs>
</Router>
);
}
}

Pass props into TabIcon with React Native Router Flux

I'm using react-native-router-flux in my app and want to pass in paths to png images for my TabIcon components. I know I could just make a different tab icon component for each tab, but these icons would be exactly the same except for the image source and I want to find a DRY way to accomplish my goal. Where in my scenes can I pass in the image path?
Here is my TabIcon component:
const TabIcon = ({ selected, title, image }) => {
const tabStyle = selected ? styles.selected : styles.unselected
return (
<View style={tabStyle}>
<Image
style={{height: 35, width: 35}}
source={require(image)}
/>
</View>
)
}
My scenes:
const Scenes = Actions.create(
<Scene key='root'>
<Scene key='tabbar' tabs={true} tabBarStyle={styles.tabBarStyle}>
<Scene key='tab1' title='Feed' icon={TabIcon}>
<Scene
key='Feed'
component={Feed}
title='Feed'
initial={true}
/>
</Scene>
<Scene key='tab2' title='Create' icon={TabIcon}>
<Scene
key='Create'
component={Create}
title='Create'
/>
</Scene>
<Scene key='tab3' title='Leaderboard' icon={TabIcon}>
<Scene
key='leaderboard'
component={Leaderboard}
title='Leaderboard'
/>
</Scene>
</Scene>
</Scene>
)
EDIT
I have tried passing in the image like so
const Scenes = Actions.create(
<Scene key='root'>
<Scene key='tabbar' tabs={true} tabBarStyle={styles.tabBarStyle}>
//HERE
<Scene key='tab1' title='Feed' icon={TabIcon} image={'../images/feed.png'}>
<Scene
key='matchupsFeed'
component={MatchupsFeed}
title='Feed'
initial={true}
/>
</Scene>
...
...
...
Within my TabIcon component if I console.log(image) it prints out "../images/feed.png" but I get this error in the simulator:
Unknown named module: '../images/feed.png'
After taking a look at this SO question, I figured it out:
const TabIcon = ({ selected, title, image }) => {
const selectColor = selected ? '#ED1B25' : '#FFF'
return (
<View style={[styles.tabStyle, {borderBottomColor: selectColor}]}>
<Image
style={{height: 35, width: 35}}
// Change HERE
source={image}
/>
</View>
)
}
Scenes
const Scenes = Actions.create(
<Scene key='root'>
<Scene key='tabbar' tabs={true} tabBarStyle={styles.tabBarStyle}>
//Change HERE
<Scene key='tab1' title='Feed' icon={TabIcon} image={require('../images/feed.png')}>

React Native Router Flux componentDidMount Fires in the Wrong Component

I have an alert to fire on a component's componentDitMount which is NOT an initial route (MainHome in this case). But when another component that is initial (MySchedule) is loaded it displays the alert. The routes are:
export default class Example extends React.Component {
render() {
return <Router createReducer={reducerCreate}>
<Scene key="modal" component={Modal} >
<Scene key="root" hideNavBar={true}>
<Scene key="tabbar" component={NavigationDrawer}>
<Scene key="main" tabs={true} default="tab2" >
<Scene key="my_schedule" component={MySchedule} hideTabBar={true} navBar={NavBar} initial={true} />
<Scene key="intro" component={Initial} hideTabBar={true} navBar={NavBar} />
<Scene key="home" component={Home} hideTabBar={true} navBar={NavBar} />
<Scene key="main_home" component={MainHome} hideTabBar={true} navBar={NavBar} />
</Scene>
</Scene>
</Scene>
<Scene key="error" component={Error}/>
</Scene>
</Router>;
}
}
And in the component MainHome's componentDidMount the alert is fired.
componentDidMount() {
Alert.alert(
'“Welcome...',
[
{text: 'OK'}
]
);
}
So in the initial component (MySchedule in this case) should not display the alert but it does and I can't figure out why. Your help would be much appreciated.
This is how NavigationView works.
<View
style={this.props.style}>
{this.props.navigationState.children.map(this._renderScene)}
</View>
NavigationExperimental is changing a lot, so this could change.
See https://github.com/facebook/react-native/issues/6579