Wix React Native Navigation TopBar buttons can't override in android - javascript

I used setDefaultOptions in react-native-navigation to set a global topbar button on the right side using rightButtons property.
But on some screens, I want to override that global button and set a new button. So I used mergeOptions method inside the component that I want the new button on the topbar.
It works only on iOS but on android. I tried different ways to fix this issue. But couldn't find any solution.
To demonstrate let's imagine the global button is Notification. Also let's imaging I'm gonna use that in many screens except Profile Screen. Please check the below images.
The first two images are from android. Third one is from iOS. You can see on android Profile Screen has notification button on the topbar. It should be Edit button just like in iOS.
Image: 1
Android: 1
Image: 2
Android: 2
Image: 3
iOS: 1
Here is my code.
index.js
import { Navigation } from "react-native-navigation";
import App from './App';
import Notification from "./src/components/Notification";
import Profile from "./src/screens/Profile";
const defaultNavigationOptions = {
topBar: {
rightButtons: [{
id: 'com.myApp.Notification',
component: {
id: 'com.myApp.Notification',
name: 'com.myApp.Notification'
}
}],
}
}
Navigation.registerComponent('com.myApp.WelcomeScreen', () => App);
Navigation.registerComponent('com.myApp.Profile', () => Profile);
Navigation.registerComponent('com.myApp.Notification', () => Notification);
Navigation.events().registerAppLaunchedListener(() => {
Navigation.setDefaultOptions(defaultNavigationOptions);
Navigation.setRoot({
root: {
bottomTabs: {
children: [
{
stack: {
id: 'HOME_TAB',
children: [{
component: {
id: 'com.myApp.WelcomeScreen',
name: 'com.myApp.WelcomeScreen',
},
}],
options: {
bottomTab: {
text: 'Home'
}
}
}
},
{
stack: {
id: 'PROFILE_TAB',
children: [{
component: {
id: 'com.myApp.Profile',
name: 'com.myApp.Profile',
},
}],
options: {
bottomTab: {
text: 'Profile'
}
}
}
}
]
}
}
})
});
Profile.js
import { StyleSheet, Text, View } from 'react-native'
import React, { useEffect } from 'react'
import { Navigation } from 'react-native-navigation'
const Profile = (props) => {
useEffect(() => {
Navigation.mergeOptions(props.componentId, {
topBar: {
rightButtons: [{
id: 'edit',
text: 'Edit'
}]
}
})
}, [])
return (
<View>
<Text>Profile</Text>
</View>
)
}
const styles = StyleSheet.create({})
export default Profile;
I tried Profile.options = {} method as well. But no luck.
I'm using:
react-native-navigation: 7.28.1
react-native: 0.64.2

Related

React-elastic-carousel only functional after resizing window

I've just started using the react-elastic-carousel package and am running into an issue on page load. Everything loads up on page load/refresh, but when I click the arrow to move the carousel, the items aren't rotating. Only upon resizing the window do the products re-format correctly, and then I can continue to use the buttons normally from then on. I've commented out all of my CSS thinking that it was maybe clashing with the package's CSS but it did nothing. I know that this package uses Resize Observer, but am not sure if that would be the issue or not. I've attached my code for the component that's using the carousel as well as a link to the Github of the react-elastic-carousel package. Any direction or advice is appreciated!
import React from 'react';
import axios from 'axios';
import RelatedProducts from './RelatedProducts.jsx';
import OutfitList from './OutfitList.jsx';
import Carousel from "react-elastic-carousel";
//Custom styles for carousel//
const breakPoints = [
{ width: 1, itemsToShow: 1 },
{ width: 550, itemsToShow: 2 },
{ width: 768, itemsToShow: 3 },
{ width: 1200, itemsToShow: 4 },
];
class RelatedProductsList extends React.Component {
constructor(props) {
super(props);
this.state = {
products: []
}
this.getRelated = this.getRelated.bind(this);
}
componentDidUpdate(prevProps) {
if (prevProps.mainProduct.id !== this.props.mainProduct.id) {
this.getRelated()
}
}
getRelated() {
axios.get(`/api/${this.props.mainProduct.id}`)
.then((results) => {
this.setState({
products: results.data
})})
.catch((err) => console.log(err));
};
render() {
return (
<div>
<Carousel breakPoints={breakPoints}>
{this.state.products.map((id, index) => {
return (
<RelatedProducts productId={id} key={index} mainProduct={this.props.mainProduct} updateCurrentProduct={this.props.updateCurrentProduct}/>
)
})}
</Carousel>
</div>
);
}
};
export default RelatedProductsList;
Github of the carousel package

How to get react jsx "to: "/profile"" to redirect and load the profile page?

throughout my app I am using reach router to handle navigation between my pages.
However, I found a navbar component that I enjoy and brought it into my app. I am not sure why, but the "to: "/profile"" button does not actually navigate and load my http://localhost:3000/profile page.
It does change the html address to show http://localhost:3000/profile, but it does not redirect and load the profile page. I have to refresh the browser for it to do so.
Any ideas on how to get this "My Profile" button to actually redirect and load the profile page? Could I use reach router "navigate(/"profile")" in this syntax? It doesn't seem to fit when I try. Thanks!
Navbar.js
import { BorderStyle } from "#material-ui/icons";
import React from "react";
import * as ReactNavbar from "react-responsive-animate-navbar";
import Logo from "../Assets/Media/ToolioLogoSmall.png"
import { navigate, Link } from "#reach/router"; //not using this currently, but it is used for navigation throughout the rest of my app.
export default function Navbar() {
console.log(ReactNavbar.ReactNavbar)
return (
<div style={style.background}>
<ReactNavbar.ReactNavbar style={style.background}
color="rgb(25, 25, 25)"
logo={Logo}
menu={[
{ name: "HOME", to: "/Explore" },
{ name: "ARTICLES", to: "/articles" },
{ name: "My Profile", to: "/profile" },
{ name: "CONTACT", to: "/contact" },
]}
social={[
{
name: "Linkedin",
url: "https://www.linkedin.com/",
icon: ["fab", "linkedin-in"],
},
{
name: "Facebook",
url: "https://www.facebook.com/",
icon: ["fab", "facebook-f"],
},
{
name: "Instagram",
url: "https://www.instagram.com/",
icon: ["fab", "instagram"],
},
{
name: "Twitter",
url: "http://www.twitter.com/",
icon: ["fab", "twitter"],
},
]}
/>
</div>
);
}
Well, I saw the package you have used:
import * as ReactNavbar from "react-responsive-animate-navbar
found that you are using the provided sample code of this package.
the "menu" here is used for the presentational purpose, I don't think the package has used it as a router link or navlink.
Wrap each of the menu objects as NavLink something like this:
menu={[
{ name: "HOME", to: "/Explore" },
{ name: "ARTICLES", to: "/articles" },
{ name: "My Profile", to: "/profile" },
{ name: "CONTACT", to: "/contact" },
]}
try this instead:
menu={[
{ name: "HOME", to: {<Link to="/explore"/>} },
{ name: "ARTICLES", to: {<Link to="/articles"/>} }
]}
or you can use navlaink too.
#Tina
I appreciate you taking the time to respond!! I implemented the snipped you suggested but it looks like the syntax is off for some reason. I also installed and imported react-router-dom and used .
Here is the current code shown in the image below. Any ideas on getting your suggestion to work? I assume the end solution here will be some sort of workaround.
import { BorderStyle } from "#material-ui/icons";
import React from "react";
import * as ReactNavbar from "react-responsive-animate-navbar";
import Logo from "../Assets/Media/ToolioLogoSmall.png"
import { Auth } from "aws-amplify";
import { navigate } from "#reach/router";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function Navbar({ setSignedIn }) {
console.log(ReactNavbar.ReactNavbar)
return (
<Router>
<div style={style.background}>
<ReactNavbar.ReactNavbar style={style.background}
color="rgb(25, 25, 25)"
logo={Logo}
menu={[
{ name: "Home", to: {<Link to="/explore"/>} },
{ name: "My Profile", to: {<Link to="/articles">} },
{ name: "About Us", to: {<Link to="/AboutUs"/>} },
]}
social={[
{
name: "Linkedin",
url: "https://www.linkedin.com/",
icon: ["fab", "linkedin-in"],
},
{
name: "Facebook",
url: "https://www.facebook.com/",
icon: ["fab", "facebook-f"],
},
{
name: "Instagram",
url: "https://www.instagram.com/",
icon: ["fab", "instagram"],
},
{
name: "Twitter",
url: "http://www.twitter.com/",
icon: ["fab", "twitter"],
},
]}
/>
<button
style={style.signouticon}
onClick={() => {
(async function () {
try {
await Auth.signOut({ global: true });
setSignedIn(undefined);
navigate("/");
} catch (error) {
console.log(error);
}
})();
}}
>
sign out
</button>
</div>
</Router>
);
}
const style = {
background: {
backgroundColor: "black",
borderStyle: "10px black"
},
};

Import ES Module in react native unidentified

I want to import screen to my react navigation but when i import class React.Component its unidentified
my routes.js
import * as Screens from '../screens/index';
import {FontIcons} from '../assets/icons';
export const MainRoutes = [
{
id: 'LoginMenu',
title: 'Marketing',
icon: FontIcons.login,
screen: Screens.GridV1,
children: [
{
id: 'Login1',
title: 'Login V1',
screen: Screens.GridV1,
children: []
},
{
id: 'Login2',
title: 'Login V2',
screen: 'GridV2',
children: []
},
{
id: 'SignUp',
title: 'Sign Up',
screen: 'GridV2',
children: []
},
{
id: 'password',
title: 'Password Recovery',
screen: 'GridV2',
children: []
},
]
}
];
My screens/index.js
export * from './navigation';
export * from './dash';
When i check the Screens import with
console.log(Screens);
Everythings is well. But when i execute
console.log(Screens.GridV1);
i cant reach the GridV1 class
Please help me to solve my problem here. Thanks you
From your chrome snapshot of Screens, it shows that at that moment you console.log, Screens object only contains one element {__esModule: true}. GridV1, GridV2 and all other modules were resolved late with a delay.
Therefore you should see it works with setTimeout, ex:
setTimeout( () => console.log(Screens.GridV1), 100 );
But the real problem still hides behind. Normally import javascript module won't have such side effect, it should have works as you expected. Check if there are any special initialization mechanism of those modules.

How to navigate from a child Stack Navigator back to parent while resetting navigation stack at the same time, in React Native

I've read countless react-navigation docs, and I know there is way to do this, but it's definitely what I would call non-trivial and definitely non-intuitive.
I have a root navigation stack:
export const NavigationStack = StackNavigator({
Splash: {
screen: Splash
},
Signup: {
screen: Signup
},
Login: {
screen: SignIn
},
ForgottenPassword: {
screen: ForgottenPassword
},
Discover: {
screen: Discover
},
ProfileShow: {
screen: ProfileShow
}
}, {
headerMode: 'none'
})
The ForgottenPassword screen is a child Stack Navigator:
import { StackNavigator } from 'react-navigation'
import PasswordResetProcess from './index'
const ForgottenPassword = StackNavigator({
ResetPassword: {
screen: PasswordResetProcess
}
}, {
headerMode: 'none'
})
export default ForgottenPassword
On that index.js Container Component, there is a sub-component that I pass navigation to, like this:
switch (lastCompletedStep) {
case NEW_RESET_REQUEST:
return <InputTel navigation={navigation} />
case INPUT_TEL:
return <ResetPassword navigation={navigation} />
That ResetPassword component is the one in question. It triggers an action creator and passes this.props.navigation into the action creator:
await props.handleResetSubmit(token, props.navigation)
From inside this action creator, props.navigation is available as navigation. I can do this fine:
navigation.navigate('Discover') // see how this is from the root Navigation Stack
I cannot, however, do this:
navigation.dispatch({
type: 'Navigation/RESET',
index: 0,
actions: [{ type: 'Navigate', routeName: 'Discover' }]
})
It throws this error:
[edit] I just tried this and it also generated the same error:
navigation.dispatch(NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Discover' })]
}))
How do I reset the stack while navigating to Discover from here?
I feel like the answer is to navigate to discover and reset the stack at the same time as some kind of child operation, but I don't know where to begin putting that together. The react-navigation documentation is horrendous for illustrating child to parent operations.
Here is my best guess at what it approximately has to look like:
navigation.dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Discover',
actions: [{ type: 'Reset', index: 0, key: null }]
})
I just solved it with this code:
navigation.dispatch(NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'Discover' })]
}))
The secret was to add key: null, which I have seen people doing before. It is a very important element for times when you are resetting.
Here is the documentation I found that illustrates it:
https://github.com/react-community/react-navigation/issues/1127
I think this works because NavigationActions has knowledge of the root navigation stack, so it works for the same reason navigation.navigate('Discover') worked (in the context of my code in this question).
in version >2 of react navigation, NavigationActions.reset() doesnt work.
You should use StackActions.reset() instead:
import { NavigationActions, StackActions } from 'react-navigation';
const resetStackAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Discover' })],
});
this.props.navigation.dispatch(resetStackAction);

Adding navbar buttons to react-native-navigation while using react-native-meteor

I'm using react-native-navigation in combination with react-native-meteor. Since Meteor 1.3 it's recommended to use createContainer method when using React. However, if I remove 'export default' from class definition and move it to export default createContainer(params=>{...}, MyClass), I loose definition of nav bar buttons. How I should write it to not loose definition of my nav bar buttons? Thanks :)
Here is the whole code of my component:
import React, {Component} from 'react';
import {
Text,
View,
StyleSheet,
} from 'react-native';
import Meteor, { createContainer } from 'react-native-meteor';
class TestScreen extends Component {
static navigatorButtons = {
rightButtons: [{
title: 'Reset',
id: 'resetButton'
}, {
title: 'Submit',
id: 'submitButton'
}]
};
constructor(props) {
super(props);
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(
this));
}
render() {
return ( < View > < Text > Some text < /Text>
</View > );
}
onNavigatorEvent(event) {
if (event.type == 'NavBarButtonPress') {
if (event.id == 'resetButton') {
// reset here
}
if (event.id == 'submitButton') {
// submit here
}
}
}
}
export default createContainer(params => {
const handle = Meteor.subscribe('records');
return {
records: Meteor.collection('records').findOne(),
};
}, TestScreen);
You can set them dynamically on navigator:
this.props.navigator.setButtons({
rightButtons: [
{ title: 'Reset', id: 'resetButton' },
{ title: 'Submit', id: 'submitButton' }
]
});

Categories

Resources