Setting styles to a custom component inside navigationOption in react native - 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?

Related

Dispatching Action on the component button of React Native

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.

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

How to put this.props data into headerRight selector?

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)

React Native - Conditional Back Button Based on State

Below is a simple example of what I'm trying to do. I have headerLeft in the navigation bar, but would like to make that disappear (so the user can't click back) when the user clicks the button (Take the Challenge) and thereby sets the state variable 'next' to true. Is this possible to do? If so, any suggestions on how?
export default class Challenge extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: "5 Day Challenge",
headerTintColor: "white",
headerStyle: { backgroundColor: "black" },
headerTitleStyle: { fontWeight: "bold", fontSize: moderateScale(15) },
headerLeft: (
<Button onPress={() => navigation.goBack(null)}>
{" "}
<MaterialCommunityIcons
name="arrow-left"
size={28}
/>
</Button>
)
});
constructor(props) {
super(props);
this.state = {
next: false,
};
}
render() {
return (
<View>
<Button
onPress={() =>
this.setState({ next: true })}
>
<Text >
TAKE THE CHALLENGE
</Text>
</Button>
</View>
)}
}
You can use the this.props.navigation.setParams({...});
export default class Challenge extends React.Component {
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
if (state.params !== undefined) {
return {
title: "5 Day Challenge",
headerTintColor: "white",
headerStyle: { backgroundColor: "black" },
headerTitleStyle: { fontWeight: "bold", fontSize: moderateScale(15) },
headerLeft: state.params.showBack ? (
<Button onPress={() => navigation.goBack(null)}>
{" "}
<MaterialCommunityIcons
name="arrow-left"
size={28}
/>
</Button>
) : null
}
}
};
constructor(props) {
super(props);
this.state = {
next: false,
};
}
componentDidMount() {
this.props.navigation.setParams({
showBack: true
});
}
onClick = () => {
this.setState({ next: true })
this.props.navigation.setParams({
showBack: false
});
}
render() {
return (
<View>
<Button
onPress={() => this.onClick()} >
<Text >
TAKE THE CHALLENGE
</Text>
</Button>
</View>
)
}
}
PS : I hope it will work, I didn't test that code.

React native header button event inside datepicker

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')
}
}