I'm trying to filter which images from the array get displayed based on the search value.. but array isn't being rendered at all anymore - react-native

My searchbar value is passed to the component that renders my images array, I'm having trouble getting it to filter the images and render the matches.
import React, { Component } from 'react';
import { View, Dimensions, Image, Text, TouchableOpacity } from 'react-native';
var images = [
require('../assets/IMG-0028.jpeg'),
require('../assets/IMG-0048.jpeg'),
require('../assets/IMG-0064.jpeg'),
require('../assets/IMG-0089.jpeg'),
require('../assets/IMG-0119.jpeg'),
require('../assets/IMG-0151.jpeg'),
require('../assets/IMG-0152.jpeg'),
require('../assets/IMG-0153.jpeg'),
require('../assets/IMG-0154.jpeg'),
require('../assets/IMG-0155.jpeg'),
require('../assets/IMG-0184.jpeg'),
require('../assets/IMG-0221.jpeg'),
require('../assets/IMG-0268.jpeg'),
require('../assets/IMG-0309.jpeg'),
require('../assets/IMG-0320.jpeg'),
require('../assets/IMG-0474.jpeg'),
require('../assets/IMG-0707.jpeg'),
require('../assets/IMG-0860.jpeg')
];
var { width, height } = Dimensions.get('window');
class CardComponent extends Component {
renderHome = () => {
console.warn(this.props.search);
var search = this.props.search;
return images
.filter(images => search.indexOf(images.index) !== -1)
.map((image, index) => {
return (
<TouchableOpacity onPress={() => console.warn(index)} key={index}>
<View
key={index}
style={[
{ width: width / 3 },
{ height: height / 3 },
{ marginBottom: 2 },
index % 3 !== 0 ? { paddingLeft: 2 } : { paddingLeft: 0 }
]}
>
<Image
style={{ flex: 1, width: undefined, height: undefined }}
source={image}
/>
</View>
</TouchableOpacity>
);
});
};
render() {
return (
<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
{this.renderHome.bind(this)()}
</View>
);
}
}
export default CardComponent;
For some reason this code doesn't display any images, and I can't tell if my search is working.

Related

How to set the alignment for the header when using NavigationCardStack?

I've followed the example here and then tried to add a header. I've managed to get the title to show the key and the back navigation to show the key for the previous card in the stack.
The problem I have is that I cannot figure out how to align the icon and text for the back action. If I add flow: 1 to the style then it just disappears. If I add any align option then nothing changes. Funnilly enough, changing flexDirection works, as does changing the margins for left and right.
Right now, the icon and text appear to be aligned along the top edge.
I'm not sure if it's a text issue or an issue with the size of the container. Note that I've tried textAlignVertical: 'center' on the text to no avail.
How do I do this?
Does anyone know how to solve?
The code in question:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*
* Refer: http://facebook.github.io/react-native/docs/navigation.html
*/
import React, { Component } from 'react';
import {
AppRegistry,
NavigationExperimental,
PixelRatio,
ScrollView,
StyleSheet,
View,
Text,
TouchableHighlight
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
Header: NavigationHeader,
} = NavigationExperimental;
export default class BleedingEdgeApplication extends Component {
constructor(props, context) {
super(props, context);
this.state = {
navigationState: {
index: 0,
routes: [{key: 'Home'}]
}
}
this._onNavigationChange = this._onNavigationChange.bind(this);
}
_onNavigationChange(type) {
// extract the navigation state from the current state
let {navigationState} = this.state;
switch(type) {
case 'push':
// push a new route, which in our case is an object with a key value
const route = {key: ':' + Date.now()};
// use the push reducer provided by NavigationStateUtils
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
// Pop the current route using the pop reducer
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
render() {
return (
<MyVerySimpleNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
}
class TappableRow extends Component {
render () {
return (
<TouchableHighlight
style={styles.row}
underlayColor="#D0D0D0"
onPress={this.props.onPress}>
<Text style={styles.buttonText}>
{this.props.text}
</Text>
</TouchableHighlight>
);
}
}
class MyVeryComplexScene extends Component {
render() {
return (
<ScrollView style={styles.scrollView}>
<Text style={styles.row}>
Route: {this.props.route.key}
</Text>
<TappableRow
text="Tap me to load the next scene"
onPress={this.props.onPushRoute}
/>
<TappableRow
text="Tap me to go back"
onPress={this.props.onPopRoute}
/>
</ScrollView>
);
}
}
class MyVerySimpleNavigator extends Component {
constructor(props, context) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._renderScene = this._renderScene.bind(this);
this._renderHeader = this._renderHeader.bind(this);
this._renderLeftHeader = this._renderLeftHeader.bind(this);
}
render() {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
style={styles.navigator}
/>
);
}
_renderHeader(sceneProps) {
return (
<NavigationHeader
{...sceneProps}
renderTitleComponent={() => (
<NavigationHeader.Title>
{sceneProps.scene.route.key}
</NavigationHeader.Title>
)}
renderLeftComponent={this._renderLeftHeader}
/>
);
}
_renderLeftHeader(sceneProps) {
if(sceneProps.scene.index > 0) {
return (
<TouchableHighlight onPress={this._onPopRoute}>
<View style={styles.backView}>
<Icon style={styles.navBarIcon} name='ios-arrow-back' size={27} />
<Text style={styles.backText}>{sceneProps.scenes[sceneProps.scene.index - 1].route.key}</Text>
</View>
</TouchableHighlight>
);
}
return (
<TouchableHighlight>
<View style={styles.backView}>
<Icon style={styles.navBarIcon} name='ios-menu' size={27} />
</View>
</TouchableHighlight>
);
}
_renderScene(sceneProps) {
return (
<MyVeryComplexScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
}
const styles = StyleSheet.create({
navigator: {
flex: 1,
},
scrollView: {
marginTop: 64
},
row: {
padding: 15,
backgroundColor: 'white',
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
backView: {
// flex: 2,
height: 50,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'flex-start',
},
backText: {
fontSize: 12,
textAlign: 'left',
},
backChevron: {
},
navBarIcon: {
color: '#1d1d1d',
marginLeft: 8,
marginRight: 8,
justifyContent: 'center',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
AppRegistry.registerComponent('BleedingEdgeApplication', () => BleedingEdgeApplication);
I should note that I am using React Native Vector Icons. This requires copying the Ionicon font from the font's directory into the ios project and rebuilding from within xcode.
The problem was not applying styling to <TouchableHighlight> with a flex: 1. This makes the component take up the entire space and let me use flex and alignItems on the <View> that held the button and text. This made the whole styling a lot neater.
The biggest confusion was understanding that the various header components within <NavigationHeader> are all independent, hence the seperate render option for title, left and right.
The solution looks like:
The code, as working (with colored backgrounds to show the components):
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*
* Refer: http://facebook.github.io/react-native/docs/navigation.html
*/
import React, { Component } from 'react';
import {
AppRegistry,
NavigationExperimental,
PixelRatio,
ScrollView,
StyleSheet,
View,
Text,
TouchableHighlight
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
Header: NavigationHeader,
} = NavigationExperimental;
export default class BleedingEdgeApplication extends Component {
constructor(props, context) {
super(props, context);
this.state = {
navigationState: {
index: 0,
routes: [{key: 'Home'}]
}
}
this._onNavigationChange = this._onNavigationChange.bind(this);
}
_onNavigationChange(type) {
// extract the navigation state from the current state
let {navigationState} = this.state;
switch(type) {
case 'push':
// push a new route, which in our case is an object with a key value
const route = {key: ':' + Date.now()};
// use the push reducer provided by NavigationStateUtils
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
// Pop the current route using the pop reducer
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
render() {
return (
<MyVerySimpleNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
}
class TappableRow extends Component {
render () {
return (
<TouchableHighlight
style={styles.row}
underlayColor="#D0D0D0"
onPress={this.props.onPress}>
<Text style={styles.buttonText}>
{this.props.text}
</Text>
</TouchableHighlight>
);
}
}
class MyVeryComplexScene extends Component {
render() {
return (
<ScrollView style={styles.scrollView}>
<Text style={styles.row}>
Route: {this.props.route.key}
</Text>
<TappableRow
text="Tap me to load the next scene"
onPress={this.props.onPushRoute}
/>
<TappableRow
text="Tap me to go back"
onPress={this.props.onPopRoute}
/>
</ScrollView>
);
}
}
class MyVerySimpleNavigator extends Component {
constructor(props, context) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._onOpenSideNav = this._onOpenSideNav.bind(this);
this._renderScene = this._renderScene.bind(this);
this._renderHeader = this._renderHeader.bind(this);
this._renderLeftHeader = this._renderLeftHeader.bind(this);
}
render() {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
style={styles.navigator}
/>
);
}
_renderHeader(sceneProps) {
return (
<NavigationHeader
{...sceneProps}
style={styles.navHeader}
renderTitleComponent={() => (
<NavigationHeader.Title style={styles.navheadertitle}>
<Text style={styles.headerTitle}>
{sceneProps.scene.route.key}
</Text>
</NavigationHeader.Title>
)}
renderLeftComponent={this._renderLeftHeader}
/>
);
}
_renderLeftHeader(sceneProps) {
if(sceneProps.scene.index > 0) {
return (
<TouchableHighlight onPress={this._onPopRoute} style={styles.headerBackTouchableHighlight}>
<View style={styles.headerBackView}>
<Icon style={styles.headerIcon} name='ios-arrow-back' size={27} />
<Text style={styles.headerBackText}>{sceneProps.scenes[sceneProps.scene.index - 1].route.key}</Text>
</View>
</TouchableHighlight>
);
}
return (
<TouchableHighlight onPress={this._onOpenSideNav} style={styles.headerBackTouchableHighlight}>
<View style={styles.headerBackView}>
<Icon style={styles.headerIcon} name='ios-menu' size={27} />
</View>
</TouchableHighlight>
);
}
_renderScene(sceneProps) {
return (
<MyVeryComplexScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
_onOpenSideNav() {
return null;
}
}
const styles = StyleSheet.create({
navigator: {
},
navHeader: {
backgroundColor: 'red',
},
navheadertitle: {
backgroundColor: '#00ff0099',
flex: 3
},
headerTitle: {
color: '#ffffff',
backgroundColor: 'blue',
},
headerBackTouchableHighlight: {
backgroundColor: 'purple',
flex: 1,
},
headerBackView: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'darkgreen',
},
headerBackText: {
fontSize: 14,
textAlign: 'left',
color: '#ffffff',
},
headerIcon: {
color: '#ffffff',
marginLeft: 8,
marginRight: 8,
justifyContent: 'center',
},
scrollView: {
marginTop: 64
},
row: {
padding: 15,
backgroundColor: 'white',
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
AppRegistry.registerComponent('BleedingEdgeApplication', () => BleedingEdgeApplication);

React native Flatlist not unselect onPress

I have a select-able flat list. When user touches a row it selects that particular item and stores that items id in array. But when i tries to un-select item by touching selected item again it dont unselect & adds it again in array, but if i touches it again second time then it removes the item from array but still dont un-select. Below is my code for flatlist:
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
FlatList,
List,
ListItem
} from 'react-native';
import {
Container,
Header,
Item,
Input,
Button,
StyleProvider,
Icon,
Body,
Right,
StatusBar,
Card,
CardItem,
CheckBox,
Left
} from 'native-base';
export default class UserList extends Component {
constructor(props) {
super(props);
const {params} = this.props.navigation.state;
this.state = {
data: [],
SelectedUserList: params.selectedUserID.slice(),
SelectedUserListName: [],
renderedListData: [],
IsInArray: true,
selectedUserID: params.selectedUserID,
IsSelected: (new Map(): Map<string, boolean>)
}
console.log("selectedUserID" + JSON.stringify(this.state.selectedUserID))
console.log("selectedCropName" + JSON.stringify(params.SelectedUserListName))
}
press = (hey) => {
console.log('Press:'+this.state.SelectedUserList)
this.state.renderedListData.map((item) => {
if (item.id === hey.id) {
item.check = !item.check
if (item.check === true) {
this.state.SelectedUserList.push(item.id);
this.state.SelectedUserListName.push(item.name);
console.log('selected:' + item.name);
console.log(this.state.SelectedUserListName.includes(item.id))
} else if (item.check === false) {
const i = this.state.SelectedUserList.indexOf(item)
const j = this.state.SelectedUserListName.indexOf(item)
if (1 != -1) {
this.state.SelectedUserList.splice(i, 1)
this.state.SelectedUserListName.splice(j, 1)
console.log('unselect:' + item.name)
return this.state.SelectedUserList
}
}
}
})
this.setState({data: this.state.data})
}
componentDidMount() {
//Fetch Data From API
...
}
render() {
return (
<View style={styles.container}>
<View style={styles.storyContainer}>
<FlatList data={this.state.renderedListData} keyExtractor={item => item.id.toString()}
extraData={this.state}
renderItem={({item}) => {
return <TouchableOpacity style={{
flexDirection: 'row',
padding: 2
}} onPress={() => {
this.press(item)
}}>
<View style={{
flex: 3,
alignItems: 'flex-start',
justifyContent: 'center'
}}>
{<Card
style={{
width: '100%',
height: 80,
alignItems: 'center'
}}>
<CardItem style={{height: '100%'}}>
<Left>
<View style={{
flex: 1,
flexDirection: 'row',
alignItems: 'center'
}}>
<CheckBox checked={(this.state.selectedUserID.includes(item.id) || item.check ) ? true : false}
style={{marginRight: 15}}/>
<View>
<Text style={{
color: "#24466B",
fontSize: 16
}}>
{item.name}
</Text>
</View>
</View>
</Left>
</CardItem>
</Card>}
</View>
</TouchableOpacity>
}}/>
</View>
</View>
)
}
};
It defined SelectedUserList as:
SelectedUserList: params.selectedUserID.slice()
because when user selects list and clicks ok , it pushes that array to previous screen and if user tries again to re select it pushes array to list screen and previously selected item will automatically re-select on list screen.
onPress was working fine previously but when i added slice with states, it stoped unselecting. I added slice with array states because to set state as it is on previous screen
In press, I guess the condition whould be i != -1 and not 1 != -1. Please check it.

Changes does not reflect in View for two way data binding of React Native

I am creating a card list from dynamic JSON object with come from webservice. I want two way data binding when click on each card item. When i click on each card item and change something data changes for corresponding JSON object but does not changes in View.
Here is my code
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
ImageBackground,
Image,
Dimensions,
TouchableOpacity,
TextInput,
ScrollView,
ActivityIndicator
} from 'react-native';
import { Container, Header, Content, Button, Tab, Tabs, Footer, Left, Body, Right, Icon, Title, Card, CardItem, List, ListItem } from 'native-base';
export default class natureOfInvestment extends React.Component {
static navigationOptions = {
header: null
};
constructor(props) {
super(props);
this.state = {
session_id: this.props.navigation.state.params.session_id,
loading: true,
investmentItems: [],
}
}
componentDidMount() {
this.onLoadSelectInvestment();
}
onLoadSelectInvestment() {
return fetch(CommonTasks.ROOT_URL + 'user/pageTwo', {
method: 'GET',
})
.then((response) => response.json())
.then((responseJson) => {
var investment = responseJson.all_categories;
var investment_items = [];
for (var data of investment) {
data.showhide = true;
data.text = '';
investment_items.push(data);
}
this.setState({
loading: false,
investmentItems: investment_items,
})
})
}
investmentType(e, item) {
if (item.showhide == true) {
item.showhide = false;
}
else {
item.showhide = true;
}
console.log(item);
}
render() {
return (
<Container>
<View>
<List style={{ paddingHorizontal: 7 }}
dataArray={this.state.investmentItems}
renderRow={(item) =>
<Card>
<CardItem style={{ backgroundColor: item.background_color, }}>
<Body>
<TouchableOpacity style={{ flexDirection: 'row', alignItems: 'center' }}
key={item.cat_id}
onPress={this.investmentType.bind(this, item)}
>
<View style={{ width: 250, paddingRight: 10 }}>
<Text style={{ color: 'white', fontSize: 17, marginLeft: 10 }}>
{item.category_name}
</Text>
</View>
<Right>
<Image
style={{ width: 18, height: 18, }}
source={require('../assets/images/right_arrow.png')}
/>
</Right>
</TouchableOpacity>
</Body>
</CardItem>
{
item.showhide ?
<View style={{ flexDirection: 'column', margin: 10 }}>
<View style={{ borderColor: 'black', borderRadius: 4, borderWidth: 0.7, }}>
<TextInput
style={{ textAlignVertical: 'top' }}
placeholder="Please write the details"
underlineColorAndroid="transparent"
multiline={true}
numberOfLines={4}
onChangeText={(text) => { item.text = text }}
/>
</View>
</View>
: null
}
</Card>
}
/>
</View>
</Container>
);
}
}
I want to show/hide the TextInput view or change data within the JSONobject that will reflect in View of the List.
Thanks in advance.
After looking at the native-base documentation about List I see that they use the View component so you will have to re render the List component you can do that like that:
onLoadSelectInvestment() {
return fetch(CommonTasks.ROOT_URL + 'user/pageTwo', {
method: 'GET',
})
.then((response) => response.json())
.then((responseJson) => {
var investment = responseJson.all_categories;
var investment_items = [];
for (var data of investment) {
data.showhide = true;
data.text = '';
investment_items.push(data);
}
this.setState({
loading: false,
investmentItems: investment_items,
})
List.forceUpdate();
})
}
But please note that it will re render the whole list.

Showing list empty message at the center of the screen in a FlatList using ListHeaderComponent

I am using React-Native version 0.43.0 which does not support ListEmptyComponent of FlatList. Hence I am using ListHeaderComponent to render a view when the list is empty,
import React, { Component } from 'react';
import { Text, View, StyleSheet,FlatList } from 'react-native';
class App extends Component {
constructor(props) {
super(props);
this.state = {
listData: []
}
}
render() {
return (
<View style={styles.container}>
<FlatList
renderItem={() => null}
data={this.state.listData}
ListHeaderComponent={() => (!this.state.listData.length?
<Text style={styles.emptyMessageStyle}>The list is empty</Text>
: null)
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1
},
emptyMessageStyle: {
textAlign: 'center',
//My current hack to center it vertically
//Which does not work as expected
marginTop: '50%',
}
});
As you can see from the image the text is not centered vertically
Any idea how to center it vertically in a FlatList?
I have already tried applying justifyContent, alignItems etc but no use.
This is a link to the snack.expo - https://snack.expo.io/S16dDifZf
They fixed ListEmptyComponent in this pr https://github.com/facebook/react-native/pull/18206. But they will ship in 0.56.
You can add a style to the FlatList.
const styles = StyleSheet.create({
container: {
flex:1
},
listStyle: {
justifyContent: 'center'
},
emptyMessageStyle: {
textAlign: 'center',
}
});
render() {
return (
<View style={styles.container}>
<FlatList style={styles.listStyle}
renderItem={() => null}
data={this.state.listData}
ListHeaderComponent={() => (!this.state.listData.length ?
<Text style={styles.emptyMessageStyle}>The list is empty</Text>
: null)}
/>
</View>
);
}
This will center the items in the list, when the list is not empty. You may have to apply another style (when the list is not empty), if you don't prefer the non empty style.
Link to snack.expo
Another option - without changing FlatList style - conditionally rendering FlatList based on this.state.listData.length
render() {
return (
<View style={styles.container}>
{
this.state.listData.length?
(<FlatList
renderItem={() => null}
data={this.state.listData}
/>)
:
(
<View style={styles.emptyListStyle}>
<Text style={styles.emptyMessageStyle}>The list is empty</Text>
</View>
)
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1
},
emptyListStyle: {
flex: 1,
justifyContent: 'center'
},
emptyMessageStyle: {
textAlign: 'center',
}
});
This is the snack.expo
Hope this will help you
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
disableVirtualization={false}
data={this.state.data}
renderItem={this.renderItem}
ListEmptyComponent={this.renderEmptyContainer()}
/>
}
/>
Place your UI in the renderEmptyContainer() method and boom, Empty container will show up whenever your list is empty
As a temporary workaround you can conditionally set a style to the contentContainer to center only the empty set like this
<FlatList
contentContainerStyle={customers.length === 0 && styles.centerEmptySet}
data={customers}
renderItem={({ item, index }) => (
/// Your item here
)}
keyExtractor={(item, index) => {
return String(index);
}}
ListEmptyComponent={<EmptySetCustomer />}
/>
And styles like this
centerEmptySet: { justifyContent: 'center', alignItems: 'center', height: '100%' }
Then in 2-3 weeks we can update to 0.56 and remove the workaround

Adjacent JSX elements must be wrapped in an enclosing tag (React-Native)

How can I solve that, because i can't figure out how to solve. I change the some parts of the code, change the root and add some codes on root,js to try not crash the entire app, but still show me this error. thanks for the help.
import React, { Component } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default class Tabs extends Component {
state = {
activeTab: 0
}
render({children} = this.props) {
return (
<div>
<View style={styles.container}>
<View style={styles.tabsContainer}>
{children.map(({ props: { title } }, index) => {
<TouchableOpacity
style={[
// Default style for every tab
styles.tabContainer,
index === this.state.activeTab ? styles.tabContainerActive : []
]}
// Change active tab
onPress={() => this.setState({ activeTab: index }) }
// Required key prop for components generated returned by map iterator
key={index}
>
<Text style={styles.tabText}>
{title}
</Text>
</TouchableOpacity>
<View style={styles.contentContainer}>
{children[this.state.activeTab]}
</View>
</View>
</div>
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
tabsContainer: {
flexDirection: 'row',
paddingTop: 30,
},
tabContainer: {
flex: 1,
paddingVertical: 15,
borderBottomWidth: 3,
borderBottomColor: 'transparent',
},
tabContainerActive: {
borderBottomColor: '#FFFFFF',
},
tabText: {
color: '#FFFFFF',
fontWeight: 'bold',
textAlign: 'center',
},
contentContainer: {
flex: 1
}
});
You are missing a closing view tag for the tabs container and you can remove the div:
render({children} = this.props) {
return (
<View style={styles.container}>
<View style={styles.tabsContainer}>
{children.map(({ props: { title } }, index) =>
<TouchableOpacity
style={[
// Default style for every tab
styles.tabContainer,
index === this.state.activeTab ? styles.tabContainerActive : []
]}
// Change active tab
onPress={() => this.setState({ activeTab: index }) }
// Required key prop for components generated returned by map iterator
key={index}
>
<Text style={styles.tabText}>
{title}
</Text>
</TouchableOpacity>
}
</View>
<View style={styles.contentContainer}>
{children[this.state.activeTab]}
</View>
</View>
);
};

Resources