I have tried to bind the event inside header of datepicker. But its not working.
and the another problem is could n't access the function inside of header part.
Here is my code:
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
var isNavigate = true;
var searchStartDate = "";
return {
title: "Tracking" ,
headerRight: (
<View style={[styles.right, { flexDirection: 'row' }]}>
<DatePicker
cancelBtnText='Cancel'
confirmBtnText='Done'
hideText='true'
mode="date"
customStyles={{
dateIcon: {
position: 'absolute',
right: 0,
top: 4,
marginBottom: 5,
marginLeft: 0,
flex: 1
},
}}
onDateChange={() => params.Tracking()} />
</View>
)
}
};
Tracking() {
}
constructor(props) {
super(props);
this.state = {
loading: false,
showCalendar: false
}
}
Try to add simple component in headerRight, if it works then you can add DatePicker or any other component. consider following example:
class Home extends Component {
static navigationOptions = ({ navigation }) => ({
title: 'Title',
headerRight: (
<Button
title='Button'
onPress={Home.instance.onButtonPress}
/>
)
});
constructor(props) {
super(props);
Home.instance = this;
}
onButtonPress = () => {
alert('I am pressed')
}
}
Related
I am relatively new in React Native and I tried to read a lot of tutorials everywhere, still I don't get the proper solution on my issue. What is the proper way of calling the action clearCart() and at the same time navigate? I am having this error regarding the dispatch when pressed the button.
It seems I use componentDidMount() or useEffect() and separately call the clearCart() but I would gladly welcome any suggestions as it will be additional for me.
//other imports
import {clearCart} from 'src/modules/cart/actions';
//other imports..
class WebviewPayment extends Component {
constructor(props, context) {
super(props, context);
const {route} = props;
this.state = {
loading: true,
uri: route?.params?.uri ?? '',
};
}
handleContinue = () => {
const {navigation, dispatch} = this.props;
dispatch(clearCart());
navigation.pop();
navigation.navigate(homeTabs.shop);
};
//other components here
render() {
const {loading, uri} = this.state;
const {t} = this.props;
return (
<ThemedView isFullView>
<WebView
source={{uri}}
onNavigationStateChange={data => this.handleResponse(data)}
style={styles.webView}
onLoadStart={() => this.setState({loading: false})}
/>
{loading && (
<View style={styles.viewLoading}>
<ActivityIndicator size="large" color="black"/>
</View>
)}
<Container style={styles.footer}>
<Button
title={t('cart:text_shopping')}
onPress={this.handleContinue}
/>
</Container>
</ThemedView>
);
}
}
const styles = StyleSheet.create({
webView: {
flex: 1,
backgroundColor: 'transparent',
},
viewLoading: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
},
footer: {
marginVertical: margin.big,
},
});
WebviewPayment.propTypes = {};
export default withTranslation()(WebviewPayment);
In my actions.js, I have:
export function clearCart() {
return {
type: Actions.CLEAR_CART,
};
}
I got it working now and this might help others in case they come across with the same issue as mine. The working code is as follow:
//other imports
import {clearCart} from 'src/modules/cart/actions';
import {connect} from 'react-redux';
//other imports..
class WebviewPayment extends Component {
constructor(props, context) {
super(props, context);
const {route} = props;
this.state = {
loading: true,
uri: route?.params?.uri ?? '',
};
}
handleContinue = () => {
const {navigation} = this.props;
this.props.clearCart();
navigation.pop();
navigation.navigate(homeTabs.shop);
};
//other components here
render() {
const {loading, uri} = this.state;
const {t} = this.props;
return (
<ThemedView isFullView>
<WebView
source={{uri}}
onNavigationStateChange={data => this.handleResponse(data)}
style={styles.webView}
onLoadStart={() => this.setState({loading: false})}
/>
{loading && (
<View style={styles.viewLoading}>
<ActivityIndicator size="large" color="black"/>
</View>
)}
<Container style={styles.footer}>
<Button
title={t('cart:text_shopping')}
onPress={this.handleContinue}
/>
</Container>
</ThemedView>
);
}
}
const styles = StyleSheet.create({
webView: {
flex: 1,
backgroundColor: 'transparent',
},
viewLoading: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
},
footer: {
marginVertical: margin.big,
},
});
WebviewPayment.propTypes = {};
const mapDispatchToProps = (dispatch) => ({
clearCart: () => dispatch(clearCart()),
});
export default connect(
null,
mapDispatchToProps,
)(withTranslation()(WebviewPayment));
I used react-redux connect then mapDispatchToProps to pass the clearCart() into props.
I have a expo app written with react-navigation ^3.12.0
I have a theme selection on my app, meaning you can click on color circle, and every screen on the app will have the background color whatever you chose, however the react-navigation doesn't change the header color, react-navigation only changes color accordingly if you navigate to different screen and go back to the screen where you can choose theme colors.
This is my code.
class AccountScreen extends Component {
static navigationOptions = ({navigation}) => {
const {params} = navigation.state;
return {
title: navigation.getParam("otherParam", "Account"),
headerTintColor: "white",
headerStyle: {
elevation: 0,
shadowOpacity: 0,
borderBottomWidth: 0,
backgroundColor: navigation.getParam("themeBackgroundColor"),
},
headerLeft: (
< TouchableOpacity
style = {
{
paddingLeft: 15
}
}
onPress = {()
=>
navigation.dispatch(DrawerActions.toggleDrawer())
}
>
<
Feather
name = "arrow-left"
size = {24}
color = "#ffffff" / >
< /TouchableOpacity>
),
headerRight: <
View
style = {
{
flexDirection: "row"
}
}><
/View>,
}
;
};
constructor(props) {
super(props);
this.state = {
loading: false,
};
}
componentDidMount() {
// https://github.com/facebook/react-native/issues/12981
YellowBox.ignoreWarnings(["Setting a timer"]);
const {theme, navigation} = this.props;
navigation.setParams({
themeBackgroundColor: theme.backgroundColor,
});
}
render() {
renderItem = ({item}) => (
< TouchableOpacity
onPress = {()
=>
this.props.setTheme(item.key)
}>
<
View
style = {
[
style.itemContainer,
{
backgroundColor: item.backgroundColor,
}
,
]
}
/>
< /TouchableOpacity>
)
;
return (
< FlatList
style = {
[
style.container,
{
backgroundColor: this.props.theme.backgroundColor
}
,
]
}
data = {this.props.themes}
numColumns = {3}
contentContainerStyle = {
{
flexGrow: 1,
justifyContent
:
"center",
left
:
"14%",
}
}
renderItem = {renderItem}
/>
)
;
}
}
Do I need to use redux? Please advise.
Edit:
This is where i handle color selection
<TouchableOpacity onPress={() => this.props.setTheme(item.key)}>
<View
style={[
style.itemContainer,
{
backgroundColor: item.backgroundColor,
},
]}
/>
</TouchableOpacity>
Ciao, try to modify your code like:
static navigationOptions = ({ navigation }) => {
const {params} = navigation.state;
return {
...
headerStyle: {
...
backgroundColor: navigation.getParam('BackgroundColor', '#ED2525'), // replace themeBackgroundColor with BackgroundColor
// #ED2525 is a default value, you can remove it if you don't need
},
...
};
};
Then on componentDidMount:
componentDidMount() {
// https://github.com/facebook/react-native/issues/12981
YellowBox.ignoreWarnings(["Setting a timer"]);
const {theme, navigation} = this.props;
navigation.setParams({
BackgroundColor: theme.backgroundColor,
});
}
Should solve your problem.
import React, {Component} from 'react';
import {Text, View,TextInput,Button,Alert,KeyboardAvoidingView,ScrollView,Dimensions,TouchableOpacity} from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import {BoxShadow} from 'react-native-shadow'
import DropdownAlert from 'react-native-dropdownalert';
import datum from './data';
import Parse from "parse/react-native";
export default class Editprofile extends React.Component {
static navigationOptions = {
title: 'Edit Profile',
headerStyle: {
backgroundColor:'#E8EDF1',
},
headerTintColor:datum.primaryColor,
headerTitleStyle: {
fontWeight: 'bold',
textAlign:"center",
flex:1
},
};
constructor(props) {
super(props)
this.state = {name:"",number:0,windowwidth:Dimensions.get('window').width,windowheight:Dimensions.get('window').height,custid:""};
}
componentDidMount() {
Parse.setAsyncStorage(AsyncStorage);
getData = async () => {
try {
const value = await AsyncStorage.getItem('nameKey')
if(value !== null) {
this.setState({name:await AsyncStorage.getItem('nameKey')
,number: await AsyncStorage.getItem('numberKey')})
const GameScore = Parse.Object.extend("Customer");
const query = new Parse.Query(GameScore);
query.equalTo("phonenumber",parseInt(this.state.number));
const results = await query.find();
for (let i = 0; i < results.length; i++) {
var object = results[i];
this.setState({custid:JSON.stringify(object.id)})
}
}
} catch(e) {
this.dropdown.alertWithType('error', 'Error', 'Error reading values');
}
}
getData();
}
updatedata = async () => {
try {
await AsyncStorage.setItem('nameKey',this.state.name)
await AsyncStorage.setItem('numberKey',this.state.number)
var P = Parse.Object.extend("Customer");
var instance = new P();
var temp=this.state.custid.replace(/['"]+/g, '')
var temptwo=temp.replace(/\//g, "")
instance.id = temptwo.replace(/['"]+/g, '')
instance.set("name",this.state.name);
instance.set("phonenumber",parseInt(this.state.number));
instance.save();
this.dropdown.alertWithType('success', 'Success', 'saved locally ');
} catch (e) {
this.dropdown.alertWithType('error', 'Error', 'Cannot able to create profile');
}
}
render() {
const shadowOpt = {
width:this.state.windowwidth*0.5,
height:this.state.windowheight*0.07,
color:"#000",
border:26,
radius:3,
opacity:0.2,
x:0,
y:3,
style:{marginVertical:5}
}
return (
<View style={{flex:1,flexDirection:'column',justifyContent:'space-evenly',alignItems:'center',backgroundColor:'#E8EDF1'}}>
<BoxShadow setting={shadowOpt}>
<TextInput
placeholderTextColor={datum.placeholderTextColor}
style={{
height: this.state.windowheight*0.07, borderColor:datum.primaryColor, borderWidth: 1,
width:this.state.windowwidth*0.5,backgroundColor:datum.primaryColor, fontWeight: '200',elevation: 2
}}
onChangeText={(value) => this.setState({name:value.trim()})}
value={this.state.name}
/>
</BoxShadow>
<BoxShadow setting={shadowOpt}>
<TextInput
placeholderTextColor={datum.placeholderTextColor}
keyboardType='number-pad'
style={{height: this.state.windowheight*0.07, borderColor:datum.primaryColor, borderWidth: 1,width:this.state.windowwidth*0.5,backgroundColor:datum.primaryColor, fontWeight: '200'}}
onChangeText={(value) => this.setState({number:value})}
value={this.state.number}
/>
</BoxShadow>
<BoxShadow setting={shadowOpt}>
<Button
onPress={()=>this.updatedata()
}
title="Signup"
color={datum.primaryColor}
accessibilityLabel="Learn more about this purple button"
/>
</BoxShadow>
<DropdownAlert ref={ref => this.dropdown = ref} />
</View>
);
}
}
I am using drawer navigation in this project but I don't understand why the header is not visible in my project it is blank, can someone say how to add a header to my component so that I can run out of complaints, I am struggling with this error for past two weeks
react-natvigation is used in the project ,
my app.js
const MyDrawerNavigator = createDrawerNavigator({
entry:{
screen:SIgnup,
navigationOptions: {
drawerLabel: () => null
},
},
Home: {
screen: HOme,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components/Drawbles/Homeicon.png")}
resizeMode="contain"
style={{ width: 20, height: 20 }}
/>
)
}
},
Editprofile: {
screen: EDit,
navigationOptions: {
drawerLabel: 'Edit Profile',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components/Drawbles/EditProfile.png")}
resizeMode="contain"
style={{ width: 20, height: 20, tintColor: tintColor }}
/>
)
}
},
Offerrides: {
screen: OFferrides,
navigationOptions: {
drawerLabel: 'Offer Rides',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components//Drawbles/Offerride.png")}
resizeMode="contain"
style={{ width: 20, height: 20 }}
/>
)
}
},
Paymentmethod: {
screen: PAymentmethod,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components/Drawbles/Paymentmethod.png")}
resizeMode="contain"
style={{ width: 20, height: 20 }}
/>
)
}
},
Otp: {
screen: OTp,
navigationOptions: {
drawerLabel: () => null //hide header if not needed so whole screen slide
},
}
},{});
const MyApp = createAppContainer(MyDrawerNavigator);
export default MyApp;
Drawer navigation by default doesn't display the header,it just display the drawing menu. As it is you can open the drawer by sliding right,if you want to open it with a header you have to do a component and use it on screens you want. Heres a nice example of headers: https://react-native-training.github.io/react-native-elements/docs/header.html
Try change this:
static navigationOptions = {
...props...
}
To this:
static navigationOptions = () => {
return {
...props...
}
}
I have a screen set a <Switch /> in header by using react navigation.
I know how to get this.state value from outside function by this.props.navigation.setParams.
But I don't know how to send the <Switch /> value to outside function.
I try it with the code onValueChange={value => params.handleThis(value)}
but in my case handleThis is key-value, it can't get the value obviously.
this.props.navigation.setParams({
handleThis: this.changeSwitch
});
How to send <Switch /> onChange value to outside function ?
Here is my code:
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
title: 'Title',
headerStyle: {
backgroundColor: ColorSetting.headerColor,
elevation: null,
},
headerTitleStyle: {
fontWeight: '300',
fontFamily: 'FFF Tusj',
fontSize: 18
},
headerRight:
<View style={{ marginRight: 15 }}>
<Switch
onValueChange={value => params.handleThis()}
value={params.switchOn}
onTintColor='#444444'
tintColor='#444444'
/>
</View>,
};
};
constructor(props) {
super(props);
this.state = {
switchOn: false
};
}
componentDidMount() {
this.props.navigation.setParams({
handleThis: this.changeSwitch
});
}
changeSwitch = () => {
const { switchOn, titleVersion } = this.state;
this.props.navigation.setParams({ switchOn: !switchOn });
this.setState({ switchOn: !switchOn });
}
Any help would be appreciated. Thanks in advance.
You can use params.handleThis as the handler, there is no need for an inline function.
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
title: 'SO Question',
headerStyle: {
elevation: null,
},
headerTitleStyle: {
fontFamily: 'FFF Tusj',
fontSize: 18
},
headerRight:
<View style={{ marginRight: 15 }}>
<Switch
onValueChange={params.handleThis}
value={params.switchOn}
onTintColor='#444444'
tintColor='#444444'
/>
</View>,
};
};
after that changeSwitch will receive the new value as the first parameter.
changeSwitch = (switchOn) => {
this.props.navigation.setParams({ switchOn });
this.setState({ switchOn });
}
Here's a working example
I want to set styling for a custom component, inside navigationOptions in react native. But the stying doesnt work and it give an error saying. Same styling is working in another text box of the same screen.
P:S: I could achieve this by doing this? Am I doing this correct? Is this the proper way of handling this?
class WorkoutScreen extends Component {
constructor(props) {
super(props);
this.state = {
searchText: ""
};
}
componentDidMount() {
this.props.navigation.setParams({
searchWorkouts: this.searchWorkoutHandler,
onChangeSearchText: this.onChangeSearchTextHandler,
searchText: this.state.searchText
});
}
// on change search text
onChangeSearchTextHandler = value => {
this.setState({
searchText: value
});
this.props.navigation.setParams({
searchText: value
});
};
// search workouts
searchWorkoutHandler = () => {
alert("Searching Workouts");
};
render() {
return (
<View style={styles.container}>
<Text>Im Here</Text>
</View>
);
}
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
headerTitle: (
<SearchInput
style={styles.searchInput}
value={params.searchText}
source={Search}
borderRadius={50}
placeholder="Search / Filter"
onChangeText={value => params.onChangeSearchText(value)}
onPress={() => params.searchWorkouts()}
/>
),
headerTitleStyle: { width: "100%", alignItems: "center" },
headerStyle: {
paddingRight: 10,
paddingLeft: 10
},
headerLeft: (
<ClickableIcon
source={Bookmark}
onIconPressed={() => alert("Notifications Clicked Workout")}
/>
),
headerRight: (
<ClickableIcon
source={Movements}
onIconPressed={() => alert("Add New Clicked")}
/>
)
};
};
}
const styles = StyleSheet.create({
container: {
flex: 1
},
scrollView: {
backgroundColor: "#ffffff"
},
searchInput: {
height: 45,
color: "gray",
fontSize: 18
}
});
export default WorkoutScreen;
How can I overcome this?