React Native : Custom Tabbar - reactjs

React native : How can I custom tab bar like image below??

1) you can use this library to create tabs react-native-scrollable-tab-view.
2) Then it has a prop (renderTabBar) here you can pass your own custom tab bar.
<ScrollableTabView renderTabBar={() => <DefaultTabBar tabStyle={{color: 'red'}} />} />
one tip that i am giving.
make a file name it CustomTabBar copy all the code from libraries DefaultTabBar and past it in your CustomTabBar.
now change its designs the way you want it to be and use it like this. This way you will have to do the least amount of work.
<ScrollableTabView renderTabBar={() => <CustomTabBar/>} />

Maybe this is the solution you need
1, Install: switch-react-native
npm i switch-react-native
2, Using lib:
import React, { Component } from 'react';
import { View } from 'react-native';
import { Switch } from 'switch-react-native';
class SwitchExample extends Component {
render() {
return (
<View>
<Switch
height={40}
width={300}
activeText={`Active Text`}
inActiveText={`InActive Text`}
onValueChange={(value: any) => console.log(value)}
/>
</View>
);
}
}

Related

Why nativewind styles doesn't work if the styling is done at component level?

React-native styling using Nativewind works fine if the styling is done at App.Js. Like here:
<NavigationContainer>
<View>
<Text className = "text-red-500">Hello</Text>
</View>
</NavigationContainer>
But if the styling is done at component level, then it doesn't work anymore.
return (
<NavigationContainer>
<HomeScreen/>
</NavigationContainer>
);
HomeScreen Component:
import { View, Text } from 'react-native'
import React from 'react'
const HomeScreen = () => {
return (
<View>
<Text className = "text-red-500">Hello</Text>
</View>
)
}
export default HomeScreen
You'll need to tell nativewind the locations of where your components reside by adding this to your tailwind.config.ts
content: ["./App.{js,jsx,ts,tsx}", "./<custom directory such as src>/**/*.{js,jsx,ts,tsx}"],
reference: https://www.nativewind.dev/quick-starts/react-native-cli
If you setup folder in tailwind.config.js and still not work then delete nodemodule then install it again and it will work.
This works for me:
content: ["./App.{js,jsx,ts,tsx}", "./<custom directory such as src>/**/*.{js,jsx,ts,tsx}"]

Component to call all material-ui Icon in React

I want to implement a component which calls the corresponding icon from material-ui. I've made it work when manually calling it.
import MenuIcon from '#material-ui/icons/Menu';
export const Icon = (props) => {
return (
<div>
<MenuIcon/>
</div>
)
}
The problem is I don't know how to change the import for all icons.
I want to call this component the following way:
<Icon icon="MenuIcon" className="someClass" />
<Icon icon="LocationOn" className="someClass" />
<Icon icon="Notifications" className="OthersomeClass" />
I can't figure out how to import all icons and how to change my Icon component to work for any icon from the material-ui package.
Something like this...
import React from 'react';
import * as IconList from '#material-ui/icons/Menu'; //error
export const Icon = (props) => {
const {icon, className} = props;
return (
<`${icon}` className={className} /> {//error}
)
}
Any ideas?
You should be able to import all the icons using named imports or the star imports (* as).
Star imports should look like this
import * as Icons from "#material-ui/icons";
<Icon icon={Icons.Menu} className="someClass" />
<Icon icon={Icons.AccessAlarmIcon} className="someClass" />
Named imports should look like this
import { Menu, AccessAlarmIcon } from "#material-ui/icons";
<Icon icon={Menu} className="someClass" />
<Icon icon={AccessAlarmIcon} className="someClass" />
You can also refactor your Icon component to utilize the React children prop, that way you can better compose each icon on the Icon component.
So it should look something like this
import React from 'react';
export const Icon = ({ children }) => {
return (
<>{children}</>
)
}
Then you can use it like this
<Icon>
<Menu className="someClass" />
</Icon>
<Icon>
<AccessAlarmIcon className="someClass" />
</Icon>
PS:
Your star imports were from '#material-ui/icons/Menu' as opposed to just '#material-ui/icons' and that caused an error

React Native Web with Next JS and React Navigation

I am trying to decide on the best way to set up routing in my React Native Web project. I am using expo and followed this guide to use Next JS https://docs.expo.io/versions/latest/guides/using-nextjs/ so I have App.js like this:
import index from "./pages/index";
import alternate from "./pages/alternate";
import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";
const AppNavigator = createStackNavigator(
{
index,
alternate
},
{
initialRouteName: "index"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;
My concern is how best to handle routing. I have my index.js page setup like this currently.
import * as React from 'react'
import { StyleSheet, Button, Text, View } from 'react-native'
export default function App ({navigation}) {
return (
<View style={styles.container}>
{/* Native route */}
<Button
title="Go to Details"
onPress={() => navigation.navigate("alternate")}
/>
{/* Web route */}
<Text style={styles.link} accessibilityRole="link" href={`/alternate`}>
A universal link
</Text>
</View>
);
}
As you can see this is currently requiring separate code to render a Native vs Web route. I am wondering what is the best way to handle this sort of rendering. I looked into using React Navigation for web and wouldn't be opposed to this but it seems like I should probably stick with the Next Router.
Thanks in advance for any advice on handling conditional rendering like this.
Use reactnavigation web support for that
https://reactnavigation.org/docs/en/web-support.html
import { createSwitchNavigator } from "#react-navigation/core";
import { createBrowserApp } from "#react-navigation/web";
const MyNavigator = createSwitchNavigator(routes);
const App = createBrowserApp(MyNavigator);
// now you can render "App" normally
There is import { Platform } from 'react-native':
{Platform.OS === 'web' ? (
<Text
style={styles.link}
accessibilityRole="link"
href={`/alternate`}
>
A universal link
</Text>
) : (
<Button
title="Go to Details"
onPress={() => navigation.navigate("alternate")}
/>
)}

this.props in component does not contain navigation property

I want to navigate from one screen to another by this.props.navigation.navigate('Second Screen') but property 'navigation' does not contain in the props. Get error:
Property 'navigation' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'
import React, { Component } from "react";
import styles from "./style";
import { Keyboard, Text, View, TextInput, TouchableWithoutFeedback, KeyboardAvoidingView } from 'react-native';
import { Button } from 'react-native-elements';
export default class SignInScreen extends Component {
render() {
return (
<KeyboardAvoidingView style={styles.containerView} behavior="padding">
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.loginScreenContainer}>
<View style={styles.loginFormView}>
<Text style={styles.logoText}>Book Market</Text>
<TextInput placeholder="Email" placeholderTextColor="#c4c3cb" style={styles.loginFormTextInput} />
<TextInput placeholder="Password" placeholderTextColor="#c4c3cb" style={styles.loginFormTextInput} secureTextEntry={true} />
<Button
buttonStyle={styles.loginButton}
onPress={this.props.navigation.navigate('Home')}
title="Login"
/>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
}
}
You can only access it through the parent element. Pass navigation as a prop to its children to use it
Eg:
<Child navigation={this.props.navigation} />
You can do what was already suggested, pass the navigation prop down to your target component
Ex:
<TargetComponent navigation={this.props.navigation} />
Or you can use withNavigation HOC from react-natigation.
Ex:
import {withNavigation} from 'react-navigation'
...
export default withNavigation(Child)
Hope it helps.
Okay, I find a solution. At first, I need to change extends of my class like
export default class SignInScreen extends Component<{navigation: any}>
Then change onPress action:
<Button
buttonStyle={styles.loginButton}
onPress={() => this.onSignInPress()}
title="Login"
/>
private onSignInPress() {
this.props.navigation.navigate('Home');
}
I know this is an old question, but since the problem of undefined navigation property still exists at least for those who use EXPO managed approach, I'll write my solution hopefully it'll save someone's day.
After searching for hours I found no way to fix this bug and find a way to add navigation property to this.props. Finally, I solved the problem by using NavigationContext in this way:
<NavigationContainer>
<NavigationContext.Provider>
<Stack.Navigator>
...
</Stack.Navigator>
</NavigationContext.Provider>
</NavigationContainer>
Then get the navigation in a consumer:
<NavigationContext.Consumer>
{navigation => {
return (
<Button onPress={() => this.onButtonPress(navigation)} />
);
}}
</NavigationContext.Consumer>
And finally:
onButtonPress(navigation) {
try {
navigation.navigate(RouteNames.FORGOTTEN_PASSWORD_SCREEN);
} catch (e) {
this.setState({ errors: [e.message] });
}
}

"props should be defined" but how?

I am new to react and react native.
I am trying to set up a simple app, using this tutorial
https://github.com/aksonov/react-native-router-flux/blob/master/docs/MINI_TUTORIAL.md
I have set up my app with this command
create-react-native-app my-project
I start the app and see it in expo on my phone.
Then
npm i react-native-router-flux --save
I replace the contents of App.js with all the code from that tutorial. I also create the required PageOne.js and PageTwo.js.
I then get an immediate error on my phone.
[react-native-router-flux] props should be defined
assert
c:\my path...\react-native-router-flux\src\Util.js#34:10
How do I define these props? What do I need to do to get this working?
Extras!
The code is exactly as in that tutorial,
App.js
import React, { Component } from 'react';
import { Router, Scene } from 'react-native-router-flux';
import PageOne from './PageOne';
import PageTwo from './PageTwo';
export default class App extends Component {
render() {
return (
<Router>
<Scene key="root">
<Scene key="pageOne" component={PageOne} title="PageOne" initial={true} />
<Scene key="pageTwo" component={PageTwo} title="PageTwo" />
</Scene>
</Router>
)
}
}
PageOne.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { Actions } from 'react-native-router-flux';
export default class PageOne extends Component {
render() {
return (
<View style={{margin: 128}}>
<Text onPress={Actions.pageTwo}>This is PageOne! </Text>
</View>
)
}
}
PageTwo.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { Actions } from 'react-native-router-flux';
export default class PageTwo extends Component {
render() {
return (
<View style={{margin: 128}}>
<Text onPress={Actions.pageOne}>This is PageTwo!</Text>
</View>
)
}
}
I don't really have a conclusive answer. Perhaps just being new to a lot of different moving parts had caused something to get out of line.
I updated some magic numbers in package.json and app.json according to the upgrade table on this page
https://github.com/react-community/create-react-native-app/blob/master/VERSIONS.md
and things started to work again.
I suppose that some of my thrashing around installing various react things had gotten the installed versions out of step. Perhaps if I really understood the ecosystem it would seem clear to me but it feels like a bunch of string and bailing wire at the moment!

Resources