wants to change current button on clicked - react-native

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

Related

React native three dots menu appearing on left side

i'm creating a screen using react-native-paper. When i use a Appbar as header with three dots menu, the options appear at the wrong side of the screen. It should appear at the right side, not the left one.
My code:
import React, { useEffect,useState } from 'react'
import {
SafeAreaView,
StyleSheet,
Platform
} from 'react-native'
import {connect} from 'react-redux'
...
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
import {Appbar,Menu} from 'react-native-paper'
import MComponent from './subpages/component'
const Tab = createMaterialTopTabNavigator();
const TAG = 'TAG'
const MPage = ({ navigation,handleLoadData,isLoading }) => {
useEffect(() => {
handleLoadData()
}, [])
const [openMenu,setOpenMenu] = useState(false)
return (
<SafeAreaView style={styles.container}>
<Menu
style={styles.menu}
visible={openMenu}
onDismiss={()=>{
setOpenMenu(false)
}}
anchor={
<Appbar.Header
statusBarHeight={0}
>
<Appbar.BackAction
onPress={()=>{
navigation.goBack()
}}
/>
<Appbar.Content
title="App Screen"
/>
<Appbar.Action icon="dots-vertical" onPress={()=>{
setOpenMenu(true)}}
/>
</Appbar.Header>
}
>
<Menu.Item onPress={() => {
setOpenMenu(false)
handleLoadServiceOrders()
}} title="Option 1" />
<Menu.Item onPress={() => {}} title="Option 2" />
</Menu>
<Loading
loading={isLoading}
/>
<Tab.Navigator>
<Tab.Screen name={OPTIONS.PAGE_A} component={MComponent} />
<Tab.Screen name={OPTIONS.PAGE_B} component={MComponent } />
</Tab.Navigator>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
marginTop: Platform.OS === 'android' ? 30 : 0,
justifyContent: 'center',
flex:1
}
})
...
Images showing what happened:
https://imgur.com/a/xq3Gcac
I'm using react-native with react-native-paper lib to create the Appbar. The Menu component also belongs to react-native-paper.
You have to pass the correct anchor prop. It accepts a React.ReactNode or an Object like this type { x: number; y: number }. I posted an example for you with the anchor anchor={{ x: windowWidth, y: 100 }}. This will work. Also you don't have to combine Appbar with Menu. It will work if you seperate them.
<Appbar.Header>
<Appbar.BackAction onPress={_goBack} />
<Appbar.Content title="Title" subtitle="Subtitle" />
<Appbar.Action icon="magnify" onPress={openMenu} />
<Appbar.Action icon="dots-vertical" onPress={openMenu} />
</Appbar.Header>
<Provider>
<View>
<Menu
visible={visible}
onDismiss={closeMenu}
anchor={{ x: windowWidth, y: 100 }}>
<Menu.Item onPress={() => { }} title="Item 1" />
<Menu.Item onPress={() => { }} title="Item 2" />
<Divider />
<Menu.Item onPress={() => { }} title="Item 3" />
</Menu>
</View>
</Provider>
The menu position is set relative to its anchor. In your original example, the entire Appbar is the anchor, so the menu appears to the left side of that.
Instead, you can make the anchor just be the Appbar.Action, which will make the menu appear next to the vertical dots.
Here is similar example using a Menu:
<Card.Title
title={item.name}
subtitle={item.description}
style={{overflow: 'visible'}}
left={(props) => <Avatar.Icon {...props} icon={require('../assets/icon.png')} />}
right={(props) =>
<Menu
visible={menuvisible}
onDismiss={handleMenuDismiss}
anchor={ <IconButton {...props} icon="dots-vertical" onPress={handleMenuShow}></IconButton>}
>
<Menu.Item onPress={() => {alert('item1')}} title="Item 1" />
<Menu.Item onPress={() => {}} title="Item 2" />
<Menu.Item onPress={() => {}} title="Item 3" />
</Menu>
}
/>

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

CardList React Native

I'm new to React and was wondering if anyone could assist me. I'm trying to create a card list. I have done this part however I'm showing an image inside my card which does not render properly. The entire card becomes 1/12 of a row size. If I remove the List part then card renders properly.
Below is my Code:
import React, { Component } from "react";
import { Image } from "react-native";
import {
Container,
Header,
Title,
Content,
Text,
Button,
Icon,
FooterTab,
Left,
Right,
Card,
CardItem,
Thumbnail,
ListItem,
List,
Body
} from "native-base";
import styles from "./styles";
const datas = [
{
route: "Header1",
text: "Only Title",
restImage: require("../../../assets/restaurants/Mc.png")
},
{
route: "Header2",
text: "Icon Buttons",
restImage: require("../../../assets/restaurants/Mc.png")
}
];
const logo = require("../../../assets/logo.png");
//const cardImage = require("../../../assets/Mc.png");
//const cardImage2 = require("../../../assets/NY.png");
class Anatomy extends Component {
render() {
return (
<Container style={styles.container}>
<Header
style={{ backgroundColor: "#FFAB00" }}
androidStatusBarColor="#FF8F00"
iosBarStyle="light-content"
>
<Left>
<Button
transparent
onPress={() => this.props.navigation.navigate("DrawerOpen")}
>
<Icon name="ios-menu" />
</Button>
</Left>
<Body>
<Title>Rests</Title>
</Body>
<Right />
</Header>
<Content padder>
<List
dataArray={datas}
renderRow={data =>
<ListItem>
<Card style={styles.mb}>
<CardItem cardBody>
<Image
style={{
resizeMode: "cover",
width: null,
height: 200,
flex: 1
}}
source={data.restImage}
/>
</CardItem>
<CardItem style={{ paddingVertical: 0 }}>
<Left>
<Button transparent>
<Icon active name="thumbs-up" />
<Text>4923 Likes</Text>
</Button>
</Left>
<Body>
<Button transparent>
<Icon active name="chatbubbles" />
<Text>89 Comments</Text>
</Button>
</Body>
<Right>
<Text
button
onPress={() => this.props.navigation.navigate(data.route)}
>2KM away</Text>
</Right>
</CardItem>
</Card>
</ListItem>
}
/>
</Content>
</Container>
);
}
}
export default Anatomy;
I managed to resolve it. Did some research and just added below style to card.
<Card style={{ flex: 1 }}>
This resolved the rendering problem for me.

Why Header component in NativeBase is not on top?

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