Why Header component in NativeBase is not on top? - react-native

i got a little problem with Header component in NativeBase (UI Component for React Native). Its position should be on top. But, mine is below a white block. I don't know why its there.
Here my code
import React, { Component } from 'react';
import { Image } from 'react-native';
import {
Container,
Header,
Left,
Body,
Right,
Title,
Content,
Footer,
FooterTab,
Button,
Icon,
Text,
List,
ListItem,
Switch,
Item,
Input,
Form,
DeckSwiper,
Card,
CardItem,
Thumbnail,
View
} from 'native-base';
import { Col, Row, Grid } from "react-native-easy-grid";
import { StackNavigator } from 'react-navigation';
import Expo from "expo";
import { cards, groups_category } from '../data/dummies';
class HomeScreen extends Component {
constructor (props) {
super(props);
this.state = {
loading: true,
isUserLogin: false,
searchStatus: false
}
this.showSearch = this.showSearch.bind(this);
this.checkLoginStatus = this.checkLoginStatus.bind(this);
}
async componentWillMount() {
await Expo.Font.loadAsync({
'Roboto': require('native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
'Ionicons': require("#expo/vector-icons/fonts/Ionicons.ttf")
});
this.setState({ loading: false });
}
showSearch () {
this.setState({ searchStatus: !this.state.searchStatus });
}
checkLoginStatus () {
if (!this.state.isUserLogin) {
return this.props.navigation.navigate('Login');
} else {
return
}
}
render() {
if (this.state.loading) {
return <Expo.AppLoading />;
}
return (
<Container>
{ this.state.searchStatus &&
(<Header searchBar rounded>
<Item regular>
<Icon name='md-arrow-back' onPress={this.showSearch} />
<Input placeholder='Contoh: Jakarta Memancing'/>
<Icon name='search' />
</Item>
</Header>)
}
{ !this.state.searchStatus &&
(<Header>
<Left>
<Icon name='add' style={{color: '#FFFFFF'}} />
</Left>
<Body style={{ alignItems: 'center' }}>
<Title>Komunitas</Title>
</Body>
<Right>
<Icon name='search' style={{color: '#FFFFFF'}} onPress={this.showSearch} />
</Right>
</Header>)
}
{/* Content */}
<Content padder={true}>
<View style={{height: 470}}>
<DeckSwiper
dataSource={cards}
renderItem={item =>
<Card style={{ elevation: 3 }}>
<CardItem>
<Left>
<Thumbnail source={item.image} />
<Body>
<Text>{item.text}</Text>
<Text note>NativeBase</Text>
</Body>
</Left>
</CardItem>
<CardItem cardBody>
<Image style={{ height: 300, flex: 1 }} source={item.image} />
</CardItem>
<CardItem>
<Icon name="heart" style={{ color: '#ED4A6A' }} />
<Text>{item.name}</Text>
</CardItem>
</Card>
}
/>
</View>
<List>
<ListItem itemHeader first>
<Text>Kategori Grup</Text>
</ListItem>
{groups_category.map(group => {
return (<ListItem key={group.id}>
<Left>
<Icon name={group.icon}/>
</Left>
<Body>
<Text>{group.name}</Text>
</Body>
<Right />
</ListItem>)
}
)}
</List>
</Content>
{/* Content */}
<Footer>
<FooterTab>
<Button vertical active>
<Icon active name="home" />
<Text style={{fontSize: 9.5}}>Home</Text>
</Button>
<Button vertical>
<Icon name="megaphone" />
<Text style={{fontSize: 9.5}}>Baru</Text>
</Button>
<Button vertical>
<Icon name="notifications" />
<Text style={{fontSize: 9.5}}>Notifikasi</Text>
</Button>
<Button onPress={this.checkLoginStatus} vertical>
<Icon name="person" />
<Text style={{fontSize: 9.5}}>Profil</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
export default HomeScreen;
It results like this
As you can see the Header which has search icon is located below an empty space / white color. Why this happen ? Maybe there are a lot of friends here had experienced it before when using NativeBase UI Component.

It's because you are using StackNavigator as well. You can disable the header as below.
static navigationOptions = {
headerMode: 'none'
}

UPDATE for React Navigation 5.x
If you want to use Nativebase's header with react navigation 5, you can do it like this:
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import {
Header,
Left,
Body,
Title,
Button,
Icon,
View,
Text
} from 'native-base';
const Stack = createStackNavigator();
const Home = () => {
return (
<View>
<Text>Hello World</Text>
</View>
)
}
const CustomHeader = ({scene, previous, navigation}) => {
const {options} = scene.descriptor;
const title =
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
? options.title
: scene.route.name;
return (
<Header>
<Left>
{previous ? (
<Button transparent onPress={navigation.goBack}>
<Icon name="arrow-back" />
</Button>
) : (
undefined
)}
</Left>
<Body>
<Title>{title}</Title>
</Body>
</Header>
);
};
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={Home}
options={{
header: (props) => <CustomHeader {...props} />,
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
More of the options here https://reactnavigation.org/docs/en/stack-navigator.html

Set header null in navigation option to remove top blank space, like below
export default class Home extends React.Component {
static navigationOptions = {
title: 'Home',
header: null //used for removing blank space from top
};
}

Related

Pass props though screenstack

Im trying to pass some props to though an screenstack element in react native. I have a button which onPress will ask for a screen using react navigation like this:
<Button
title="Lees Meer"
color="#d10a10"
onPress={() => RootNavigation.navigate('Article', {
params: { title: title, text: text, image: image },
})}
/>
I want thos params to be used in the article to fill in the text, title and image. I thought I could just use them like this in the article:
function ArticleFull({ navigation, params }) {
return (
<View>
<Header/>
<Card>
<CardItem header bordered>
<Body>
<Image
style={{ width: '100%', height: 400 }}
source={{ uri: 'https://www.holland.com/upload_mm/9/a/b/68638_fullimage_zwolle_sassenpoort.jpg' }}
/>
<Text>
{params.text}
</Text>
</Body>
</CardItem>
</Card>
<Button
title="Go Back"
color="#d10a10"
width= "10%"
onPress={() => navigation.goBack()}
/>
</View>
);
}
export default ArticleFull;
In the app.js i made these screenstacks which is used to navigate to an article but i need it to contain some params which are set in the homepage using the button.
const Stack = createStackNavigator();
App.js:
export default class App extends Component {
render() {
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName="Home" >
<Stack.Screen options={{headerShown: false}} name="Home" component={HomePage} />
<Stack.Screen options={{headerShown: false}} name="Article" component={ArticleFull} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
You can pass like this:-
<Button
title="Go to Details"
onPress={() => {
/* 1. Navigate to the Details route with params */
navigation.navigate('Details', {
itemId: 86,
otherParam: 'anything you want here',
});
}}
/>
and receive like this:-
function DetailsScreen({ route, navigation }) {
/* 2. Get the param */
const { itemId } = route.params;
const { otherParam } = route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
);
}
source
Hope it helps!!!

How refresh a Flatlist with Input's text using Json API

I'm trying to refresh the Flatlist when a user type something in the search bar, but I don't know exactly how to do it.
The goal here is to display all french county returned by the API and when you enter something in the search bar the API will return only certain county
I'm using NativeBase and Axios
import React from 'react'
import { View, StyleSheet, StatusBar, ListView, FlatList} from 'react-native'
import { } from 'react-navigation'
import { Container, Header, Title, Content, Footer, FooterTab, Button, Left, Right, Body, Icon, Text, List, ListItem, Spinner, Toast, Root, Input, Item } from 'native-base';
import axios from 'axios';
import { Directions } from 'react-native-gesture-handler';
export default class Home extends React.Component {
constructor(props) {
super(props)
this.state = {
data : null,
departement : ""
}
this.fetchDepartements();
}
fetchDepartements() {
axios.get('http://192.168.1.12/APIGSBPraticien.php?departement=' + this.state.departement).then((response) => {
console.log(response.data)
this.setState({data : response.data})
})
.catch(error => {
console.log(error);
});
}
renderItem = ({ item }) => {
return (
<ListItem>
<Text>{item.PRA_Departement==null ? "Code Postal: " + item.PRA_CP:item.PRA_Departement}</Text>
</ListItem>
)
}
handleSearch = (text) => {
console.log(text);
this.setState({departement: text}),
() => { this.fetchDepartements}
};
render() {
if (this.state.data === null) {
return(
<Container style={{marginTop: 20}}>
<StatusBar translucent={false} />
<Header>
<Left>
<Button onPress={() => this.props.navigation.openDrawer()} transparent>
<Icon name='menu' />
</Button>
</Left>
<Body>
<Title>Accueil</Title>
</Body>
</Header>
<Content>
<Spinner style={{marginVertical:250}} color='green'/>
</Content>
</Container>
)
} else {
return (
<Root>
<Container style={{marginTop: 20}}>
<StatusBar translucent={false} />
<Header>
<Left>
<Button onPress={() => this.props.navigation.openDrawer()} transparent>
<Icon name='menu' />
</Button>
</Left>
<Body>
<Title>Accueil</Title>
</Body>
</Header>
<Header searchBar rounded>
<Item>
<Icon name="search" />
<Input onSubmitEditing={text => this.handleSearch(text)} placeholder="Rechercher ..." />
</Item>
</Header>
<Content>
<FlatList
data={this.state.data}
renderItem={this.renderItem}
keyExtractor={item => item.PRA_NUM}
onEndReached={()=> Toast.show({
text: 'Chargement terminé !',
type: "success",
textStyle: {marginHorizontal:100}
})}
/>
</Content>
</Container>
</Root>
)
}
}
}
I tried to get the user's input ( handleSearch() ) and update the state but once done I want to refresh the Flatlist.

how to declare a variable inside a flatList renderItem?

I'm trying to fetch the date and format it using moment , the solution i found is to store the date in a variable , and i've been having a problem with that followed this awnser since i hade the same problem . although i managed to get rid of the unexpected token error but i got my self in another one . MY FLAT LIST IS NOT SHOWING ANYMORE.
here is my code :
import React, { Component } from "react";
import {View,StyleSheet,FlatList,ListView} from "react-native";
import {Container, Header, Left, Body, Right, Title, Subtitle,Icon ,Content, Footer, FooterTab, Button, Text,Badge , List , ListItem} from 'native-base'
import Icon0 from 'react-native-vector-icons/MaterialCommunityIcons'
import Icon1 from 'react-native-vector-icons/FontAwesome'
import CountDown from 'react-native-countdown-component';
import moment from 'moment';
class Consulter extends Component{
state ={
data:[]
}
fetchData= async()=>{
const response = await fetch('http://192.168.1.4:3000/rendezvous/1');
const rendezvous =await response.json();
this.setState({data:rendezvous});
}
componentDidMount() {
this.fetchData();
}
render() {
const today = this.state.currentDate;
const day = moment(today).format("dddd");
const date = moment(today).format("MMMM D, YYYY");
return (
<Container>
<Content >
<View style ={{ flex:1}}>
<FlatList
data={this.state.data}
keyExtractor={(item,index) => index.toString()}
renderItem={({item}) =>
{let dates=item.date;
<View style={{backgroundColor:'#e6e6e6',padding:10,margin:10}}>
<ListItem icon>
<Left>
<Button style={{ backgroundColor: "white" }}>
<Icon0 active name="doctor" />
</Button>
</Left>
<Body>
<Text>Nom du Docteur : Dr. {item.nom}</Text>
</Body>
</ListItem>
<ListItem icon>
<Left>
<Button style={{ backgroundColor: "white" }}>
<Icon1 active name="calendar" />
</Button>
</Left>
<Body>
<Text>Date du rendez-vous :</Text>
<Text> dates </Text>
</Body>
</ListItem>
<ListItem icon>
<Left>
<Button style={{ backgroundColor: "white" }}>
<Icon1 active name="calendar"/>
</Button>
</Left>
<Body>
<CountDown
until= {item.date}
timetoShow={('H', 'M', 'S')}
onFinish={() => alert('finished')}
onPress={() => alert('hello')}
size={10}
/>
</Body>
</ListItem>
</View>
}}
/>
</View>
</Content>
</Container>
);
}
}
export default Consulter;
const styles =StyleSheet.create({
container : {
flex: 1,
}
})
Ps : there is no compilation errors.
you need to use a return statement, like that:
<FlatList
data={this.state.data}
keyExtractor={(item,index) => index.toString()}
renderItem={({item}) =>
{let dates=item.date;
return(
<View style={{backgroundColor:'#e6e6e6',padding:10,margin:10}}>
<ListItem icon>
...
);
renderItem expects you to return some jsx ... and you didn't
Try this:
<FlatList
data={this.state.data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item: { date } }) => (<View>// the rest of your jsx</View>)}
/>

wants to change current button on clicked

I wants to change button when I clicked on button. I have list of users. I want when I clicked on follow button the button change to following button. Right now when I clicked on button my all button changes to following button. I want to change current button. Here is my code.
import React, { Component } from "react";
import { TouchableOpacity,StatusBar,View,Modal,
TouchableHighlight,StyleSheet,Image } from "react-native";
import { connect } from "react-redux";
import { DrawerNavigator, NavigationActions } from "react-navigation";
import {} from 'react-native-elements';
import ls from 'react-native-local-storage';
import {
Container,
Header,
Title,
Content,
Text,
Button,
Footer,
FooterTab,
Left,
Body,
Right,
Input,
Item,
List,ListItem,Thumbnail
} from "native-base";
import axios from 'axios';
import Icon from 'react-native-vector-icons/FontAwesome';
export default class Search extends Component {
static navigationOptions = {
header: null
}
constructor(props) {
super(props);
this.state = {
getAllUsers:'',
checkResponce:false,
userID:'',
changeButtons:false,
};
}
componentDidMount(){
ls.get("savedata").then(data => {this.setState({ userID: data.user.id })});
axios.get( "http://172.104.217.178/api/get_users" )
.then(response => {
//alert(JSON.stringify(response));
this.setState({getAllUsers:response.data,})
// alert(JSON.stringify(this.state.getAllUsers));
})
.catch(error => alert(error.response.data));
}
Donefollow(getuserId){
axios.post( "http://172.104.217.178/api/follow_user/"+this.state.userID,{
user_id:getuserId
} )
.then(response => {
//alert(JSON.stringify(response));
if(response.data.status===1){
this.changebutton(getuserId)
}
})
.catch(error => alert(error.response.data));
}
async changebutton(followid){
this.setState({changeButtons:true})
await alert("here can i change ?")
}
render() {
let GetUersData=[];
let UsersState=this.state.getAllUsers;
for(let property in UsersState.result){
GetUersData.push( <ListItem avatar style={{height:71}}>
<Left>
<Thumbnail source={{uri:UsersState.result[property].profile_photo}} />
</Left>
<Body >
<Text style={{marginTop:15}}>{UsersState.result[property].name}</Text>
<Text note></Text>
</Body>
<Right >{this.state.changeButtons?
<Button rounded warning onPress={this.Donefollow.bind(this,UsersState.result[property].id)}>
<Text>Following</Text>
</Button>: <Button rounded warning onPress={this.Donefollow.bind(this,UsersState.result[property].id)}>
<Text>Follow</Text>
</Button>}
{/* <Button rounded warning onPress={this.Donefollow.bind(this,UsersState.result[property].id)}>
<Text>Follow</Text>
</Button> */}
</Right>
{/* <Right style={{paddingTop:10}}>
</Right> */}
</ListItem>)
}
return (
<Container style={styles.container}>
<Header>
{/* <Left>
<Text>Search</Text>
</Left> */}
<Body >
<Item rounded style={{width:"100%",height:35}}>
<Icon active color='#f39c12' size={24} style={{marginLeft:12}}name='search' />
<Input placeholder='Search'/>
</Item>
</Body>
{/* <Right>
<Button style={{backgroundColor:'transparent'}}>
<Icon style={{color:'#000'}} name="search" />
</Button>
</Right> */}
</Header>
{/*End Header*/}
<Content>
<List style={{marginTop:15}}>
{/* <ListItem avatar style={{height:71}}>
<Left>
<Thumbnail source={require('../../../images/profile_1x.png')} />
</Left>
<Body >
<Text style={{marginTop:15}}>Name</Text>
<Text note></Text>
</Body>
<Right >
<Button rounded dark>
<Text>Follow</Text>
</Button>
</Right>
<Right style={{paddingTop:10}}>
</Right>
</ListItem> */}
{GetUersData}
</List>
</Content>
<Footer>
<FooterTab>
<Button >
<Icon size={24}name="home" onPress={() =>this.props.navigation.navigate('Home') }/>
</Button>
<Button >
<Icon color='#f39c12' name="search" size={20}/>
</Button>
<Button onPress={() =>this.props.navigation.navigate('Gallery') }>
<Icon name="plus"size={20} />
</Button>
<Button onPress={() =>this.props.navigation.navigate('Following') }>
<Icon name="heart" size={20} />
</Button>
<Button onPress={() =>this.props.navigation.navigate('Profile') }>
<Icon name="user" size={20}/>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
},
topTabs:{
borderBottomWidth: 2,
width:180
},
borderLine:{
borderWidth: 1,
marginTop:10,
marginHorizontal: 40,
},
imageStyle:{
paddingTop: 10,
},
})
Here is my output before clicked
and after clicked output looks like that
I want when I clicked on whatever button just that button will change not all buttons help me please
add another state like buttonChangedUserID and set that in following method
async changebutton(followid){
this.setState({changeButtons:true, buttonChangedUserID:followid })
....
then use it to get selected user id to change button while rendering it after state change

React native scroll to on Modal

I work actually on a picker component which needs to be at center on the middle value by default.
I have created a modal with a ScrollView with ref and use the scrollTo function view on this exemple: https://snack.expo.io/SkileGr9X
Tried all but got this error :
Cannot read property 'scrollTo' of undefined
Does someone have any tip?
import React from 'react';
import { Modal,TouchableHighlight,View, StyleSheet,ScrollView,TextInput} from 'react-native';
import { Container, Header, Content, Icon,Picker, Form, Text,Left, Body, Right, Title,Button,List, ListItem} from "native-base";
const Mystyles = StyleSheet.create({
container:{
},
btnSelect:{
borderColor:'#a1a1a1',
borderWidth:1,
padding:5,
margin:10,
height:33
},
placeholderSelect:{
color:'#a1a1a1',
},
valueSelect:{
color:'black',
}
});
let scrollYPos = 0;
var itemsArray = [];
for(let i=0; i < 90;i++){
itemsArray.push(i);
}
export default class Selects extends React.Component {
constructor(props){
super(props);
this.state = {
items:itemsArray,
modalVisible: false,
isLoading:false,
selectValue:'',
placeholder:'placeholder',
type:'int'
}
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
scrollYPos = this.state.screenHeight * 1;
this.scroller.scrollTo({x: 0, y: scrollYPos});
}
selectItem = (item) =>{
this.setState({
selectValue:item,
modalVisible:false
});
this.props.returnSelect(item);
}
render(){
const { selectValue,items,placeholder } = this.state;
return (
<View style={Mystyles.container}>
<Modal
animationType="slide"
presentationStyle='formSheet'
visible={this.state.modalVisible}>
<Header>
<Left>
<Button transparent onPress={() => {this.setModalVisible(false);}}>
<Icon name='arrow-back' />
</Button>
</Left>
<Body>
<Title>Header</Title>
</Body>
<Right />
</Header>
<ScrollView ref={(scroller) => {this.scroller = scroller}}>
<List dataArray={items}
renderRow={(item) =>
<ListItem onPress={() => {this.selectItem(item);}} selected={selectValue == item}>
<Left>
<Text>{item}</Text>
</Left>
<Right>
<Icon name="arrow-forward" />
</Right>
</ListItem>
}>
</List>
</ScrollView>
</Modal>
<TouchableHighlight
style={Mystyles.btnSelect}
underlayColor="rgba(0, 0, 0, 0.1)"
onPress={() => {
this.setModalVisible(true);
}}>
<Text style={selectValue ? Mystyles.valueSelect : Mystyles.placeholderSelect}>{selectValue ? selectValue : placeholder}</Text>
</TouchableHighlight>
</View>
);
}
}
<Button transparent onPress={() => {this.setModalVisible(false);}}>
When you press this button, Modal gone so you can scroll when view gone. You have to check:
if(this.state.modalVisible){
scrollYPos = this.state.screenHeight * 1;
this.scroller.scrollTo({x: 0, y: scrollYPos});
}
BTW screenHeight is a const, don't use state.