How to put this.props data into headerRight selector? - react-native

I use react-redux to get my FlatList data and custom my header with react-navigation.
I want to add a selector in headerRight, my problem is I have no idea how to add the data into my headerRight.
Here is my header setting.
const data = [
{ key: 0, section: true, label: 'Title' },
{ key: 1, label: 'Red Apples' },
{ key: 2, label: 'Cherries' },
{ key: 3, label: 'Cranberries', accessibilityLabel: 'Tap here for cranberries' },
{ key: 4, label: 'Vegetable', customKey: 'Not a fruit' }
];
class MovieTimeList extends Component {
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.theaterCn}`,
headerStyle: {
backgroundColor: '#81A3A7',
elevation: null,
},
headerTitleStyle: {
fontWeight: '300',
fontFamily: 'FFF Tusj',
fontSize: 18
},
headerRight:
<ModalSelector
data={data}
initValue="Title"
onChange={(option)=>{ alert(`${option.label} (${option.key}) nom nom nom`) }}
/>,
});
Here is my react-redux mapStateToProps function that action is call an API to get the data:
const mapStateToProps = (state) => {
const timeList = state.listType.timeList;
return { timeList };
};
I can show the movieData in FlatList from react-redux:
render() {
const movieData = this.props.timeList;
return (
<View style={{ flex: 1 }}>
<FlatList
data={movieData}
renderItem={this.renderRow}
horizontal={false}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
I have no idea how to let the const movieData into my headerRight selector.
Any help would be appreciated. Thanks in advance.

You can set param and then use it in your header like this
componentWillReceiveProps(nextProp){
if(!isFetching && listNotUpdated){
this.props.navigation.setParams({ movieList: nextProp.timeList})
}
}
then get it in the header like this
static navigationOptions = ({ navigation }) => {
const { state } = navigation
const { movieList }= navigation.state.params
return {
title: 'Your Title',
headerRight: (
<Button
title={'Button1'}
onPress={() => {
// do something
}}
/>
),
}
}

I am not sure if this code is 100% correct, basically, you can do it by connecting ur reducer to your MovieTimeList class pass necessary prop to your component
class MovieTimeList extends Component {
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.theaterCn}`,
headerStyle: {
backgroundColor: '#81A3A7',
elevation: null,
},
headerTitleStyle: {
fontWeight: '300',
fontFamily: 'FFF Tusj',
fontSize: 18
},
headerRight:
<ModalSelector
data={data}
initValue={this.props.HeaderTitle}
onChange={(option)=>{ alert(`${option.label} (${option.key}) nom nom nom`) }}
/>,
});
const mapStateToProps = (state) => {
let HeaderTitle = state.yourreducer.headerTitle
return HeaderTitle
}
export default connect(mapStateToProps,null)(MovieTimeList)

Related

Header is not visible in react native

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...
}
}

How to send value with react-navigation in static filed?

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

React native navigationOptions calling function error

Got an error when call a function inside navigationOptions.
static navigationOptions = {
tabBarIcon: ({ tintColor })=> (
<Icon name='ios-add-circle' style={{ color: tintColor}} />
),
tabBarOnPress: () => {
this.callingFun();
},
}
callingFun = ()=> {
console.log('tabBarOnPress:');
}
Error:
You can not call callingFun in static object property. I think that you want this
static navigationOptions = ({navigation}) => {
return {
tabBarIcon: ({ tintColor }) => (
<Icon name='ios-add-circle' style={{ color: tintColor }} />
),
tabBarOnPress: () => {
navigation.getParam('callingFun')();
},
}
}
callingFun = () => {
console.log('tabBarOnPress:');
}
componentDidMount() {
const { navigation } = this.props
navigation.setParams({
callingFun: this.callingFun,
})
}
Static method calls are made on the class, not on the instance. There is no way to reference this in static method. Can only reach a static method using the name of the class.
export default class MediaTab extends React.Component {
static navigationOptions = {
tabBarIcon: ({ tintColor })=> (
<Icon name='ios-add-circle' style={{ color: tintColor}} />
),
tabBarOnPress: () => {
MediaTab.callingFun();
},
}
static callingFun = () => {
console.log('tabBarOnPress:');
}
}
I've resolved the issue be the following way:
static navigationOptions = ({ navigation }) => {
return {
headerRight: () => (
<TouchableOpacity
onPress={navigation.getParam('onPressSyncButton')}>
<Text>Sync</Text>
</TouchableOpacity>
),
};
};
componentDidMount() {
this.props.navigation.setParams({ onPressSyncButton: this._onPressSyncButton });
}
_onPressSyncButton = () => {
console.log("function called");
}
const BottomTab = createMaterialTopTabNavigator({
Active:OnlineStack
}, {
tabBarPosition: 'top',
tabBarOptions: {
activeTintColor: 'gray',
inactiveTintColor: 'white',
labelStyle: {
fontSize: 12,
fontFamily: "Choco_Cooky"
},
style: {
backgroundColor: 'black',
borderWidth: 1,
borderBottomWidth:0,
borderColor: 'gray',
},
}
/* Other configuration remains unchanged */
}
);
OnlineStack.navigationOptions = ({navigation})=>{
let { routeName } = navigation.state.routes[navigation.state.index];
let navigationOptions = {};
header: null;
if (routeName === 'Home') {
navigationOptions.tabBarVisible = false;
}
return navigationOptions;
}

Setting styles to a custom component inside navigationOption in react native

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?

How to call redux action from static navigationOptions?

I need to call a action from static navigationOptions but cannot access my action through this.props. How to call this action? I am getting error "Cannot read property 'logout' of undefined" in console.
static navigationOptions = ({navigation}) =>( {
title: 'Home',
header: <Header headerTitle={navigation.state.routeName} logoutButtonPress={() => {
this.props.logout(); // this action is not working
NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: "Welcome" })]
})
navigation.navigate('Welcome');
}
}
/>,
});
In component of screen where there is navigationOptions
componentDidMount() {
this.props.navigation.setParams({
logOut: this.actionLogOut
});
}
actionLogOut = () => {
this.props.dispatch(logOut()); };
Load function action of logout in params of navigation when componentDidMount and then
static navigationOptions = ({ navigation }) => {
return {
headerTitle: (
<Text
style={{
left: Platform.OS == "android" ? 20 : 0
}}
>
Personal Data
</Text>
),
headerRight: (
<Aux>
<Icon
name="md-notifications"
size={27}
color="#9D9B9C"
style={{ paddingLeft: 15, marginRight: 15 }}
/>
<Icon
name="ios-log-out"
size={27}
color="red"
style={{ paddingLeft: 15, marginRight: 15 }}
onPress={() => {
console.log(navigation);
navigation.state.params.logOut();
navigation.dispatch(NavigationActions.back({ index: "Login" }));
navigation.popToTop();
}}
/>
</Aux>
)
};
};
In navigationOptions use as navigation.state.params.logOut();
This component must use connect using import { connect } from "react-redux" and connect with component
You need to make the logout button as a component and bind the props explicitly from the react-redux module mapDispatchToProps
For example
const LogoutButton = ({logout}) => {
return (
<TouchableOpacity style={{height: 50, width: 100}} onPress={() => logout()}>
<Text>Logout</Text>
</TouchableOpacity>
)
}
const mapDispatchToProps = dispatch => ({
logout: () => /*dispatch your logout action here*/
})
and use it in your static navigationOptions as
static navigationOptions = ({navigation}) =>( {
title: 'Home',
header: <Header headerTitle={navigation.state.routeName}
/><Logout/>,
});
or modify your component to support this component.