accessing this.props.navigation.state.params ouside render - reactjs

I am passing a parameter from ListView to a detailed page. Can I access this parameter outside the render on my detailed page:
Below is my code to pass the parameter:
<ListView
dataSource={this.state.dataSource}
renderRow = {( rowData ) =>
<TouchableOpacity style = { styles.item } activeOpacity = { 0.4 } onPress = { this.clickedItemText.bind( this, rowData ) }>
<Text style = { styles.text }>{ rowData.ser }</Text>
</TouchableOpacity>
}
renderSeparator = {() =>
<View style = { styles.separator }/>
}
enableEmptySections = { true }
/>
</View>
clickedItemText( clickedItem )
{
this.props.navigation.navigate('Item', { item: clickedItem });
}
I can get the parameter value on my detailed page using the code below:
<View style = { styles.container2 }>
<Text style = { styles.text }>You Selected: { this.props.navigation.state.params.item.Location.toUpperCase() }</Text>
</View>
I need to do this.props.navigation.state.params.item.Location ouside render. The reason I want to do that because I want to create a ListView on my detailed page by filtering my Json data based on the passed parameter so for e.g. if the parameter passed is 2 then I want to filter my JSON data based on 2 and create another ListView.
As far as I know filtering of the JSON data can only be done outside render. I could be wrong though, I am new to react Native.
Below is my entire class for detailed page.
import React, { Component } from 'react';
import { StyleSheet, Text, View, ListView, ActivityIndicator, TextInput } from 'react-native';
import ServiceDetails from '../reducers/ServiceDetails';
class ServiceListDetails extends Component
{
constructor() {
super();
var newList = ServiceDetails.filter(obj => obj.fk === this.props.navigation.state.params.item.id);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(ServiceDetails),
};
}
static navigationOptions =
{
title: 'SecondActivity',
};
ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
render()
{
return(
<View style={styles.MainContainer}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={(rowData) => <Text>{rowData.addr}</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer:
{
justifyContent: 'center',
flex:1,
margin: 10
},
TextStyle:
{
fontSize: 23,
textAlign: 'center',
color: '#000',
},
rowViewContainer:
{
fontSize: 17,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
},
ActivityIndicator_Style:
{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
left: 0,
right: 0,
top: 0,
bottom: 0,
},
TextInputStyleClass:{
textAlign: 'center',
height: 40,
borderWidth: 1,
borderColor: '#009688',
borderRadius: 7 ,
backgroundColor : "#FFFFFF"
}
});
export default ServiceListDetails;
Below is screen shot of the error that I am getting on detailed page.
Below is the entire code of my Master Page that has a list View on it and it works fine:
import React, { Component } from 'react';
import { Text, View, StyleSheet, ListView, ActivityIndicator, TextInput, TouchableOpacity } from 'react-native';
import { Provider, connect } from 'react-redux';
import { createStore } from 'redux'
import reducers from '../reducers/ServiceReducer';
import ServiceItem from './ServiceItem';
import Icon from 'react-native-vector-icons/EvilIcons';
import ServiceDetail from './ServiceDetail';
import TestActivity from './TestActivity';
import { StackNavigator } from 'react-navigation';
import ServiceListDetails from './ServiceListDetails' ;
class AutoCompActivity extends Component {
constructor(props) {
super(props);
this.state = {
// Default Value of this State.
Loading_Activity_Indicator: true,
text:'',
}
this.arrayholder=[];
}
componentDidMount() {
const data = require('../reducers/services.json')
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
Loading_Activity_Indicator: false,
dataSource: ds.cloneWithRows(data),
}, function() {
// In this block you can do something with new state.
this.arrayholder = data ;
});
}
SearchFilterFunction(text){
const newData = this.arrayholder.filter(function(item){
const itemData = item.ser.toUpperCase()
const textData = text.toUpperCase()
return itemData.indexOf(textData) > -1
})
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newData),
text: text
})
}
ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
/*Navigate_To_Second_Activity=(ser)=>
{
//Sending the JSON ListView Selected Item Value On Next Activity.
this.props.navigation.navigate('Second', { JSON_ListView_Clicked_Item: ser });
}*/
clickedItemText( clickedItem )
{
this.props.navigation.navigate('Item', { item: clickedItem });
}
static navigationOptions =
{
title: 'MainActivity',
};
render()
{
if (this.state.Loading_Activity_Indicator) {
return (
<View style={styles.ActivityIndicator_Style}>
<ActivityIndicator size = "large" color="#009688"/>
</View>
);
}
return (
<View style={styles.MainContainer}>
<TextInput
style={styles.TextInputStyleClass}
onChangeText={(text) => this.SearchFilterFunction(text)}
value={this.state.text}
underlineColorAndroid='transparent'
placeholder="Search Here"
/>
<ListView
dataSource={this.state.dataSource}
renderRow = {( rowData ) =>
<TouchableOpacity style = { styles.item } activeOpacity = { 0.4 } onPress = { this.clickedItemText.bind( this, rowData ) }>
<Text style = { styles.text }>{ rowData.ser }</Text>
</TouchableOpacity>
}
renderSeparator = {() =>
<View style = { styles.separator }/>
}
enableEmptySections = { true }
/>
</View>
);
}
}
export default MyNewProject= StackNavigator(
{
First: {screen: AutoCompActivity},
Item: {screen: ServiceListDetails}
}
);
const styles = StyleSheet.create(
{
MainContainer:
{
justifyContent: 'center',
flex:1,
margin: 10
},
TextStyle:
{
fontSize: 23,
textAlign: 'center',
color: '#000',
},
rowViewContainer:
{
fontSize: 17,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
},
ActivityIndicator_Style:
{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
left: 0,
right: 0,
top: 0,
bottom: 0,
},
TextInputStyleClass:{
textAlign: 'center',
height: 40,
borderWidth: 1,
borderColor: '#009688',
borderRadius: 7 ,
backgroundColor : "#FFFFFF"
},
separator:
{
height: 2,
backgroundColor: 'rgba(0,0,0,0.5)'
},
item:
{
padding: 15
},
text:
{
fontSize: 18
},
});
My services.json is below
[
{
"id":0,
"ser": "Test Service",
"Location": "TestLoc",
"Phone1":"(999)-999-5050",
"SecondLoc": "TestLoc2",
"email":"test#test.com",
"sourceLat":"33.977806",
"sourceLong":"-117.373261",
"destLatL1":"33.613355",
"destLongL1":"-114.596569",
"destLatL2":"33.761693",
"destLongL2":"-116.971169",
"destAddr1": "Test Address, Test Drive",
"destAddr2": "Test Address2, Test Drive2",
"onlineURL":"",
"Phone2": "(900)-900-3333"
}
]
My ServiceDetails.json is below:
[
{
"id":"1",
"fk": "0",
"addr": "2Test addr",
"phone": "(951)-955-6200",
"LatL":"33.935547",
"Long2":"-117.191",
"Online": ""
},
{
"id":"2",
"fk": "0",
"addr": "testaddr21",
"phone": "(999)-999-9999",
"LatL":"33.977880",
"Long2":"-117.1234",
"Online": ""
}
]
How can I achieve this?

Related

Generate random QR in react-native

I have generated QR Code manually by asking user to input value but what I'm trying is to generate QR Code random(Qr should be generated from number) without asking input from user so how can I generate random QR Code by pressing button only? I'm working on project that requires random QR Code every time when they open their mobile app.
Here is my code:
import React, { Component } from "react";
import {
StyleSheet,
View,
TextInput,
TouchableOpacity,
Text,
} from "react-native";
import QRCode from "react-native-qrcode-svg";
class QrGenerator extends Component {
constructor() {
super();
this.state = {
// Default Value of the TextInput
inputValue: "",
// Default value for the QR Code
valueForQRCode: "",
};
}
getTextInputValue = () => {
this.setState({
valueForQRCode: this.state.inputValue,
});
};
render() {
return (
<View style={styles.MainContainer}>
<QRCode
//Setting the value of QRCode
value={"ComputerGen" + this.state.valueForQRCode}
//Size of QRCode
size={250}
//Background Color of QRCode
bgColor="#000"
//Front Color of QRCode
fgColor="#fff"
getRef={(ref) => (this.svg = ref)}
onPress={() => {}}
/>
<TextInput // Input to get the value to set on QRCode
style={styles.TextInputStyle}
onChangeText={(text) => this.setState({ inputValue: text })}
underlineColorAndroid="transparent"
placeholder="Enter text to Generate QR Code"
/>
<TouchableOpacity
onPress={this.getTextInputValue}
activeOpacity={0.7}
style={styles.button}
>
<Text style={styles.TextStyle}> Generate QR Code </Text>
</TouchableOpacity>
</View>
);
}
}
export default QrGenerator;
const styles = StyleSheet.create({
MainContainer: {
flex: 1,
margin: 10,
alignItems: "center",
paddingTop: 40,
},
TextInputStyle: {
width: "100%",
height: 40,
marginTop: 20,
borderWidth: 1,
textAlign: "center",
},
button: {
width: "100%",
paddingTop: 8,
marginTop: 10,
paddingBottom: 8,
backgroundColor: "#F44336",
marginBottom: 20,
},
TextStyle: {
color: "#fff",
textAlign: "center",
fontSize: 18,
},
});
What you want to do is to make a random string "inputValue" if it is empty.
getTextInputValue = () => {
if (this.state.inputValue.length === 0) {
const randomInputValue = Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
this.setState({
valueForQRCode: randomInputValue,
inputValue: randomInputValue,
});
} else {
this.setState({
valueForQRCode: this.state.inputValue,
});
}
};

How do I access a component's inner method using hooks in react-native

I am using the this, and am trying to use the "close" method. How might I call that close method once I hit a cancel alert as shown below? I believe this is my general misunderstanding of how react hooks/classes work with public methods. Any help would be appreciated!
<Swipeable
renderRightActions={renderRightActions}
onSwipeableRightOpen={() => {
Alert.alert(
"Delete " + title + "?",
"",
[
{
text: "Cancel",
onPress: () => {this.close()},
style: "cancel",
},
{ text: "Delete", onPress: () => removeItem(id) },
],
{ cancelable: true }
);
}}
leftThreshold={0}
rightThreshold={150}>Random stuff in here</Swipeable>
EDIT I rewrote it as a class:
import React from "react";
import { StyleSheet, Alert, Text, View, TouchableWithoutFeedback, Animated } from "react-native";
import { Ionicons } from "#expo/vector-icons";
import Swipeable from "react-native-gesture-handler/Swipeable";
import * as Haptics from "expo-haptics";
class ListItem extends React.Component {
constructor(props) {
super(props);
const { id, title, onClick, drag, isActive, removeItem } = this.props;
this.id = id;
this.title = title;
this.onClick = onClick;
this.drag = drag;
this.isActive = isActive;
this.removeItem = removeItem;
}
componentDidUpdate = () => {
if (this.isActive) {
// haptic feedback
Haptics.impactAsync();
}
};
renderRightActions = (progress, dragX) => {
const trans = dragX.interpolate({
inputRange: [0, 50, 100, 101],
outputRange: [-20, 0, 0, 1],
});
return (
<View style={{ width: 45, marginTop: 20, marginLeft: 1000 }}>
<Animated.Text
style={{
transform: [{ translateX: trans }],
}}></Animated.Text>
</View>
);
};
onCancel() {
console.log("WHAT");
console.log(this);
}
render() {
return (
<Swipeable
renderRightActions={this.renderRightActions}
onSwipeableRightOpen={function () {
Alert.alert(
"Delete " + this.title + "?",
"",
[
{
text: "Cancel",
onPress: this.onCancel(),
style: "cancel",
},
{ text: "Delete", onPress: () => removeItem(id) },
],
{ cancelable: true }
);
}}
leftThreshold={0}
rightThreshold={150}>
<TouchableWithoutFeedback
onPress={function () {
this.onClick();
}}
onLongPress={this.drag}
delayLongPress={200}>
<View style={listItemStyles.item}>
<View
style={{
marginTop: 7,
marginLeft: 18,
}}>
<Text style={listItemStyles.itemTitle}>{this.title}</Text>
</View>
<View style={listItemStyles.itemIcon}>
<Ionicons
name={"ios-arrow-forward"}
size={30}
style={{ marginBottom: -3 }}
color={"#E3E3E3"}
/>
</View>
</View>
</TouchableWithoutFeedback>
</Swipeable>
);
}
}
export default ListItem;
// Styles
const listItemStyles = StyleSheet.create({
// list item
item: {
padding: 3,
marginVertical: 2,
marginLeft: "2%",
marginRight: "2%",
width: "96%",
// internals
flexDirection: "row",
justifyContent: "space-between",
},
itemTitle: {
flexDirection: "row",
justifyContent: "flex-start",
color: "#333333",
fontSize: 18,
},
itemSubtitle: {
fontSize: 12,
marginLeft: 5,
},
itemIcon: {
marginTop: 2,
marginRight: 10,
flex: 1,
flexDirection: "row",
justifyContent: "flex-end",
},
});
However when I print out (this), "close" does not show up as a method.
You cannot use this because it references your outer component due to your fat-arrow functions.
The docs say Using reference to Swipeable it's possible to trigger some actions on it. close: method that closes component.
The problem here is that the great thing about the fat arrow function (it does not has its own refernce, so the outer is used).
Here in your case, that means your outer component function that render the Swipeable component.
So for that use case, you need to use a class component for the onSwipeableRightOpen prop.

error while binding the ListView

I am getting an error in my render function when I am binding my listView. Below is the code and the screen shot of the error:
My code is below. I am trying to put the search box on top of my list view. Everything was working fine, but as soon as I tried to put the search box, I started getting the above error:
import React, { Component } from 'react';
import { Text, View, StyleSheet, ListView, TextInput} from 'react-native';
import { Provider, connect } from 'react-redux';
import { createStore } from 'redux'
import reducers from '../reducers/ServiceReducer';
import ServiceItem from './ServiceItem';
import Icon from 'react-native-vector-icons/EvilIcons';
import ServiceDetail from './ServiceDetail';
const styles = StyleSheet.create({
separator: {
flex: 1,
height: StyleSheet.hairlineWidth,
backgroundColor: '#8E8E8E',
},
text: {
marginLeft: 12,
fontSize: 16,
},
header_footer_style:{
width: '100%',
height: 45,
backgroundColor: '#FF9800'
},
textStyle:{
alignSelf:'center',
color: '#fff',
fontSize: 18,
padding: 7
},
MainContainer:
{
justifyContent: 'center',
flex:1,
margin: 10
},
TextStyle:
{
fontSize: 23,
textAlign: 'center',
color: '#000',
},
});
const store = createStore(reducers);
class AutoCompActivity extends Component {
constructor(props) {
super(props);
this.state = {
// Default Value of this State
text: '',
}
this.arrayholder =[];
}
SearchFilterFunction(text){
const newData = this.arrayholder.filter(function(item){
const itemData = item.services.ser.toUpperCase()
const textData = text.toUpperCase()
return itemData.indexOf(textData) > -1
})
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newData),
text: text
})
}
renderHeader = () => {
var header = (
<View style={styles.header_footer_style}>
<Text style={styles.textStyle}> Tap the service to find the Loaction </Text>
</View>
);
return header;
};
renderInitialView() {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.setState({
dataSource : ds.cloneWithRows(this.props.services),
}, function(){
this.arrayholder=this.props.services;
});
if (this.props.detailView === true) {
return (
<ServiceDetail />
);
} else {
return (
<View style={styles.MainContainer}>
<TextInput
style={styles.TextInputStyleClass}
onChangeText={(text) => this.SearchFilterFunction(text)}
value={this.state.text}
underlineColorAndroid='transparent'
placeholder="Search Here"
/>
<ListView
enableEmptySections={true}
dataSource={this.state.dataSource}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
renderHeader={this.renderHeader}
style={{marginTop:10}}
renderRow={(rowData) =>
<ServiceItem services={rowData} />
}
/>
</View>
);
}
}
render() {
return (
<View style={styles.container}>
{this.renderInitialView()}
</View>
);
}
}
const mapStateToProps = state => {
return {
services: state.services,
detailView: state.detailView,
};
};
const ConnectedAutoCompActivity = connect(mapStateToProps)(AutoCompActivity);
const app1 = () => (
<Provider store={store}>
<ConnectedAutoCompActivity />
</Provider>
)
export default app1;
My JSON (service.json) file looks like below:
[
{
"id":0,
"ser": "Test Service",
"Location": "TestLoc",
"Phone1":"(999)-999-5050",
"SecondLoc": "TestLoc2",
"email":"test#test.com",
"sourceLat":"33.977806",
"sourceLong":"-117.373261",
"destLatL1":"33.613355",
"destLongL1":"-114.596569",
"destLatL2":"33.761693",
"destLongL2":"-116.971169",
"destAddr1": "Test Address, Test Drive",
"destAddr2": "Test Address2, Test Drive2",
"onlineURL":"",
"Phone2": "(900)-900-3333"
},
]
Any help will be highly appreciated.
Bind your functions in your constructor:
this.SearchFilterFunction = this.SearchFilterFunction.bind( this );
or use arrow functions:
SearchFilterFunction = ( text ) => { ... };
About binding functions: https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

React Native : Show parent component after closing a modal on child component

I have two components a Parent Component (App.js) and a Child Component (Logitem.js)
The parent component contains an array of child component and passes props to it.
The child component has a modal which is invoked upon clicking on a text element inside the child component.
The modal has a delete button which performs a delete operation on db.
All the above are working fine.
After the delete operation is performed I would like to show the parent component (aka) App.js but as of now the UI is still showing the modal on the child component.
How do we achieve that ?
Parent Component
import React, { Component } from 'react';
import { StyleSheet, View, Text, ScrollView, Modal, DatePickerIOS } from 'react-native';
import {
dropLogsTable,
createLogsTable,
getProfileHeightStandardfromDB,
saveLogsRecord,
populateDummyLogs,
getLogsRecords,
getLogsRecordsFromDB,
neverendingmethod,
getLogsDetailsforSaveDelete
} from '../src/helper';
import { Spinner } from '../src/Spinner';
import Logitem from '../src/Logitem';
export default class App extends Component {
state = {
allLogs:{
rows:{
_array:[{logstringdate:''}]
}
},
profileobject: {profileheight: 100, profilestandard: "XYZ"},
showspinner: true,
count:0
};
componentDidMount() {
this.fetchProfileData();
this.getAllLogs();
}
renderSpinner() {
if(this.state.showspinner) {
return <Spinner size="small" />;
}
else {
//return this.state.allLogs.rows._array.map(ae => <Text>{ae.bmi}</Text>);
return this.state.allLogs.rows._array.map(
(ae) => (
<View
key={ae.logdate}
>
<Logitem
logstringdate={ae.logstringdate}
bmi={ae.bmi}
weight={ae.metricweight}
logdate={ae.logdate}
/>
</View>
)
);
}
}
async fetchProfileData() {
console.log('Before Profile Fetch');
const result = await getProfileHeightStandardfromDB();
console.log('After Profile Fetch');
console.log('Height : '+result.profileheight);
console.log('Standard: '+result.profilestandard);
this.setState({profileobject:result}); //Line Y
return result; //Line X
}
async getAllLogs() {
console.log('Before All Logs Fetch');
const allLogs = await getLogsRecordsFromDB();
console.log('After All Logs Fetch');
console.log('Spinner State ==>'+this.state.showspinner);
if(allLogs != null)
{
this.setState({allLogs, showspinner: false});
console.log('After async spinner state ==>'+this.state.showspinner);
console.log(allLogs);
}
return allLogs;
}
render() {
return (
<ScrollView style={styles.container}>
{this.renderSpinner()}
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
top: {
width: '100%',
flex: 1,
},
bottom: {
flex: 1,
alignItems: 'center',
},
});
Child Component
import React, { Component } from 'react';
import { Text, View, Modal, DatePickerIOS, TextInput, Button } from 'react-native';
import {
deleteSelectedRecordDB
} from '../src/helper';
import { Spinner } from '../src/Spinner';
export default class Logitem extends Component {
constructor(props) {
super(props);
const { logstringdate, bmi, weight, logdate } = this.props;
}
state = {
selecteddate: '1',
selectedweight: this.props.weight,
showmodal: false,
date: new Date(86400000 * this.props.logdate),
}
async deleteSelectedRecord(){
console.log('Delete clicked');
console.log('this.state.selecteddate ==>' + this.state.selecteddate); //LINE X
const result = await deleteSelectedRecordDB(this.props.logdate);
console.log('deleteSelectedRecord after');
console.log('result ==> '+ result);
return result;
}
setModalVisible = (visible) => {
this.setState({showmodal: visible});
}
onWeightClick = () => {
this.setState({ selecteddate: this.props.logdate, showmodal: true }, () => {
console.log('Value in props==>' + this.props.logdate);
console.log('The selecteddate in the state ==> ' + this.state.selecteddate);
});
}
onDateChange(date) {
this.setState({
date: date
});
}
render() {
return (
<View style={styles.containerStyle}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.showmodal}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<View style={{marginTop: 22}}>
<DatePickerIOS
date={this.state.date}
mode="date"
onDateChange={(date) => this.onDateChange(date)}
style={{ height: 100, width: 300 }}
/>
</View>
<View style={{ marginTop: 22, borderColor: '#ddd', borderWidth: 5 }}>
<TextInput
returnKeyType="done"
keyboardType='numeric'
style={{
height: 40,
width: 60,
borderColor: 'gray',
borderWidth: 1,
}}
onChangeText={(text) => this.setState({ selectedweight: text })}
value={this.state.selectedweight.toString()}
/>
<Text>KG</Text>
<Button
title="Delete"
onPress={this.deleteSelectedRecord.bind(this)}
style={{ marginTop: 200 }}
/>
</View>
</Modal>
<View style={styles.headerContentStyle}>
<Text>{this.props.logstringdate}</Text>
<Text>{this.props.bmi}</Text>
</View>
<View style={styles.thumbnailContainerStyle}>
<Text onPress={this.onWeightClick}>{this.props.weight}</Text>
</View>
</View>
);
}
};
const styles = {
containerStyle: {
borderWidth: 1,
borderRadius: 2,
borderColor: '#ddd',
borderBottomWidth: 0,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2},
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 1,
marginLeft: 5,
marginRight: 5,
marginTop:10,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginLeft: 10,
marginRight: 10,
flexDirection: 'row'
},
headerContentStyle: {
flexDirection: 'column',
justifyContent: 'space-around'
},
};
-Simple in deleteSelectedRecord function call setModalVisible(false)

Child component won't render from function

I am trying to render a child component using the function renderHowManyAlcohol()
The component LYDSelectNumber doesn't render, the correct props are being passed down, any ideas why this doesn't render?
render() {
return (
<Flexible>
<LYDSceneContainer
goBack={this.props.goBack}
subSteps={this.props.subSteps}>
<Flexible>
{this.renderHowManyAlcohol()}
</Flexible>
</LYDSceneContainer>
</Flexible>
);
}
renderHowManyAlcohol() {
return (
<View style={styles.HowManyAlcoholContainer}>
<Text>this renders</Text>
// this component below doesn't
<LYDSelectNumber
selectedNumberValue={this.props.selectedNumberValue}
onChangeNumber={this.props.onChangeNumber}
/>
</View>
);
}
LYDSelectNumber component, styles.container shows as a number '60', which is weird, I have the styles at the bottom of the page.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Picker, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as theme from '../../../theme';
const Item = Picker.Item;
export const SelectedNumber = ({ value = 0, displayPicker = () => {} } = {}) =>
<TouchableOpacity onPress={displayPicker}>
<View style={styles.centerWrap}>
<View style={styles.selectedNumberWrap}>
<Text style={styles.selectedNumberText}>
{value}
</Text>
</View>
</View>
</TouchableOpacity>;
class LYDSelectNumber extends Component {
static propTypes = {
onChangeNumber: PropTypes.func.isRequired,
numbersRange: PropTypes.array,
style: PropTypes.any,
selectedNumberValue: PropTypes.number,
};
static defaultProps = {
numbersRange: [18, 120],
style: undefined,
selectedNumberValue: undefined,
};
render() {
return (
<View style={styles.container}>
<SelectedNumber value={this.props.selectedNumberValue} />
<Picker
style={styles.picker}
selectedValue={this.props.selectedNumberValue}
onValueChange={this.props.onChangeNumber}>
{this._renderNumbers()}
</Picker>
</View>
);
}
_renderNumbers = () => {
const [firstNumber, lastNumber] = this.props.numbersRange;
let numbersItems = [];
let n = firstNumber;
while (n <= lastNumber) {
numbersItems.push(<Item key={n} label={`${n}`} value={n} />);
n++;
}
return numbersItems;
};
}
export default LYDSelectNumber;
const styles = StyleSheet.create({
container: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
},
picker: {
position: 'absolute',
top: 0,
width: 1000,
height: 1000,
},
centerWrap: {
alignItems: 'center',
},
selectedNumberWrap: {
width: theme.utils.responsiveWidth(40),
paddingBottom: 20,
borderBottomWidth: 2,
alignItems: 'center',
borderBottomColor: theme.colors.darkGranate,
},
selectedNumberText: {
...theme.fontStyles.selectedNumber,
},
});

Resources