How to integrate react-native-tab-view using expo? - react-native

I am new to react native, I need a bit help in integrating a library react-native-tab-view. Can I get a step by step guide how to integrate it with a new project?

First run the following command in terminal
expo install react-native-gesture-handler react-native-reanimated
Paste this in your App.js and you will be done
import * as React from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
const FirstRoute = () => (
<View style={[styles.scene, { backgroundColor: '#ff4081' }]} />
);
const SecondRoute = () => (
<View style={[styles.scene, { backgroundColor: '#673ab7' }]} />
);
const initialLayout = { width: Dimensions.get('window').width };
export default function TabViewExample() {
const [index, setIndex] = React.useState(0);
const [routes] = React.useState([
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
]);
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={initialLayout}
/>
);
}
const styles = StyleSheet.create({
scene: {
flex: 1,
},
});

Related

Customize Action Sheet Message (Expo)

I'm using #expo/react-native-action-sheet, and i want to show a button in the props message.
e.g
import { useActionSheet } from "#expo/react-native-action-sheet"
const { showActionSheetWithOptions } = useActionSheet()
const onPress = () => {
// Here
**const message = '<TouchableOpacity><Text>fsdf</Text></TouchableOpacity>'**
showActionSheetWithOptions(
{
message
},
(buttonIndex) => {
}
)
}
But it is not showing the button as i want
My purpose is to add a date picker in the action sheet.
Expecting answer:
In this case, you can use another library https://gorhom.github.io/react-native-bottom-sheet/ because Action Sheet is about the list of actions.
You can place any content you need for react-native-bottom-sheet and it also supports Expo
import React, { useCallback, useMemo, useRef } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import BottomSheet from '#gorhom/bottom-sheet';
const App = () => {
// ref
const bottomSheetRef = useRef<BottomSheet>(null);
// variables
const snapPoints = useMemo(() => ['25%', '50%'], []);
// callbacks
const handleSheetChanges = useCallback((index: number) => {
console.log('handleSheetChanges', index);
}, []);
// renders
return (
<View style={styles.container}>
<BottomSheet
ref={bottomSheetRef}
index={1}
snapPoints={snapPoints}
onChange={handleSheetChanges}
>
<View style={styles.contentContainer}>
<Text>Awesome 🎉</Text>
</View>
</BottomSheet>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: 'grey',
},
contentContainer: {
flex: 1,
alignItems: 'center',
},
});
export default App;

React Native - searchApi is not a function

I am new in React Native. I try to create a simple searching food restaurant with Yelp. Unfortunately, I get an error:
"searchApi is not a function. (in 'searchApi(term)', 'searchApi' is
"")
Below my code.
useResults.js
import React, { useEffect, useState } from 'react';
import yelp from '../api/yelp';
export default () => {
const [result, setResult] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const searchApi = async (searchTerm) => {
console.log("hi there");
try {
const response = await yelp.get('/search', {
params: {
limit: 50,
term: searchTerm,
location: 'san jose'
}
});
setErrorMessage(null);
setResult(response.data.businesses);
} catch (err) {
setErrorMessage('Something Went Wrong');
}
};
/*
useEffect(() => {}); //Run the arrow function everytime the component is rendered
useEffect(() => {}, []); // Run the arrow function only when the component is first rendered
useEffect(() => {}, [value]); // Run the arrow function only when the component is first rendered, and when the value is changes
*/
useEffect(() => {
searchApi('pasta');
}, []);
return [searchApi, result, errorMessage];
};
SearchScreen.js
import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import ResultList from '../components/ResultList';
import SearchBar from '../components/SearchBar';
import useResults from '../hooks/useResults';
const SearchScreen = () => {
const [term, setTerm] = useState('');
const [searchApi, result, errorMessage] = useResults();
console.log(result);
return (
<View>
<SearchBar
term={term}
onTermChange={setTerm}
onTermSubmit={() => searchApi(term)}
/>
<View>{errorMessage ? <Text>{errorMessage}</Text> : null}</View>
<Text>We have found {result.length} results</Text>
<ResultList title="Cost Effective" />
<ResultList title="Bit Pricier" />
<ResultList title="Big Spender"/>
</View>
);
};
const styles = StyleSheet.create({
});
export default SearchScreen;
edit :
SearchBar.js
import React from 'react';
import { View, Text, StyleSheet, TextInput } from 'react-native';
import { Feather } from '#expo/vector-icons';
const SearchBar = ({ term, onTermChange, onTermSubmit }) => {
return (
<View style={styles.backgroundStyle}>
<Feather style={styles.iconStyle} name="search" size={30} color="black" />
<TextInput style={styles.inputStyle}
autoCapitalize="none"
autoCorrect={false}
placeholder="Search"
value={term}
onChangeText={onTermChange}
onEndEditing={onTermSubmit}
/>
</View>
)
};
const styles = StyleSheet.create({
backgroundStyle: {
marginTop: 10,
backgroundColor: '#F0EEEE',
height: 50,
borderRadius: 5,
marginHorizontal: 15,
flexDirection: 'row'
},
inputStyle: {
flex: 1,
fontSize: 18,
marginHorizontal: 10
},
iconStyle: {
fontSize: 35,
alignSelf: 'center'
}
});
export default SearchBar;
When I type in search bar and hit done button, I got the error above.
Seems in useResults.js file this: return [searchApi, result, errorMessage]; does not properly return the function. But the result and errorMessage return successfully.
And in this file: SearchScreen.js the error line is shown in here: onTermSubmit={() => searchApi(term)}.
How to fix this?
Try adding a callback to onChangeText.
<TextInput style={styles.inputStyle}
autoCapitalize="none"
autoCorrect={false}
placeholder="Search"
value={term}
onChangeText={() => onTermChange()} // Add fat arrow function here
onEndEditing={onTermSubmit}
/>

How to use React Hooks with react-native-tab-view

red error screen 1
Cannot read property 'configureProps' of undefined
I was using the react-tab-view with react Hooks and typescript but I have some issues somebody could give me a hand...
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Dimensions } from 'reactnative';
import { TabView, SceneMap } from 'react-native-tab-view';
const FirstRoute = () => (
<View style={[styles.scene, { backgroundColor: '#ff4081' }]} />
);
const SecondRoute = () => (
<View style={[styles.scene, { backgroundColor: '#673ab7' }]} />
);
interface Props {
navigation: any;
}
export default function Home(props: Props) {
const [rar, setRar] = useState({
index: 0,
routes: [
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
]
});
var NativeAppEventEmitter = require('RCTNativeAppEventEmitter');
return (
<View>
<TouchableOpacity onPress={props.navigation.openDrawer}>
<Text>hola desde home</Text>
</TouchableOpacity>
<TabView
navigationState={rar}
renderScene={SceneMap({
first: FirstRoute,
second: SecondRoute,
})}
onIndexChange={index => ({ index })}
initialLayout={{ width: Dimensions.get('window').width, height: 250 }}
/>
</View>
)
}
const styles = StyleSheet.create({
scene: {
flex: 0.3,
},
});
change
onIndexChange={index => ({ index })}
to
onIndexChange={index => setRar({ ...rar, index })}
that should fix the error you are facing
import React, { useState, useEffect } from 'react';
import { Container } from './styles';
import { View, StyleSheet, Dimensions } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
const LatestRoute = () => (
<View style={[styles.scene, { backgroundColor: '#ff4081' }]} />
);
const FavoritesRoute = () => (
<View style={[styles.scene, { backgroundColor: '#673ab7' }]} />
);
const AllRoute = () => (
<View style={[styles.scene, { backgroundColor: '#673ab7' }]} />
);
const styles = StyleSheet.create({
scene: {
flex: 1,
},
});
export default function Main() {
const initialState = {
index: 0,
routes: [
{ key: 'latest', title: 'Latest' },
{ key: 'favorites', title: 'Favorites' },
{ key: 'all', title: 'All' },
],
};
const [ state, setState ] = useState(initialState);
function selectTab ( index ) {
this.initialState = {
index: index,
routes: [
{ key: 'latest', title: 'Latest' },
{ key: 'favorites', title: 'Favorites' },
{ key: 'all', title: 'All' },
],
};
return setState(this.initialState);
}
return (
<Container>
<TabView
navigationState={state}
renderScene={SceneMap({ latest: LatestRoute, favorites: FavoritesRoute, all: AllRoute })}
onIndexChange={ (index) => selectTab(index) }
initialLayout={{ width: Dimensions.get('window').width, height : Dimensions.get('window').height }}
/>
</Container>
);
}

Is there a possible way to make a subheader in react native with react-native-router-flux

My problem is that I cannot do a subheader manually either because of flatlist. if I put any content where the flatlist goes the functionality of the flatlist its broken, when I scroll to the bottom to do the OnEndReached(the infinite scroll) I get back to to the top, that only happen like I said when I have content in the screen besides my flatlist, so that why I was asking if there is a possible way to do it with router-flux maybe in that way I will not have this problem.
I tried putting a View like first tag and do a manually subheader but it doesn't work.
EDIT:
Here is the image of what i have now, is there anyway to do horizontal scroll in the subheader instead of having all the tabs stacked
EDIT 2: I solved it using this plugin:
https://github.com/react-native-community/react-native-tab-view. This is my code:
import * as React from 'react';
import { Component } from 'react';
import { View, Dimensions, StyleSheet } from 'react-native';
import PostsList from '../../postsList';
import { TabView, TabBar, SceneMap } from 'react-native-tab-view';
const FirstRoute = () => (
<View>
<PostsList />
</View>
);
const SecondRoute = () => (
<View style={[{ backgroundColor: '#673ab7' }]} />
);
const ThirdRoute = () => (
<View style={[{ backgroundColor: '#673ab7' }]} />
);
const FourRoute = () => (
<View style={[{ backgroundColor: '#673ab7' }]} />
);
const FiveRoute = () => (
<View style={[{ backgroundColor: '#673ab7' }]} />
);
const initialLayout = {
height: 0,
width: Dimensions.get('window').width,
};
export default class Home extends Component {
constructor() {
super();
this.state = {
isData: true,
index: 0,
routes: [
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
{ key: 'third', title: 'Third' },
{ key: 'four', title: 'Four' },
{ key: 'five', title: 'Five' },
]
};
}
_renderTabBar = props => (
<TabBar
{...props}
scrollEnabled
indicatorStyle={styles.indicator}
style={styles.tabbar}
tabStyle={styles.tab}
labelStyle={styles.label}
/>
);
_renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
third: ThirdRoute,
four: FourRoute,
five: FiveRoute
})
_handleIndexChange = index =>
this.setState({
index,
});
render() {
return (
<TabView
navigationState={this.state}
renderTabBar={this._renderTabBar}
renderScene={this._renderScene}
onIndexChange={this._handleIndexChange}
initialLayout={initialLayout}
/>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
tabbar: {
backgroundColor: '#3f51b5',
},
tab: {
width: 120,
},
indicator: {
backgroundColor: '#ffeb3b',
},
label: {
color: '#fff',
fontWeight: '400',
},
});
This is the scrollable tabs

React Native Tab View _renderScene from another class

I try using Example React Native Tab View https://github.com/react-native-community/react-native-tab-view. I change on const FirstRoute to call from ListMahasiswa class, but there is error : FirstRoute(...) A Valid React element (or null) must be returned.
Main.js
import React, { PureComponent } from 'react';
import { View, StyleSheet } from 'react-native';
import { TabViewAnimated, TabBar, SceneMap } from 'react-native-tab-view';
import ListMahasiswa from './ListMahasiswa';
import InsertDataMhs from './InsertDataMhs';
import Coba from './Coba';
const FirstRoute = () => ListMahasiswa;
const SecondRoute = () => <View style={[ styles.container, { backgroundColor: '#673ab7' } ]} />;
export default class Main extends PureComponent {
state = {
index: 0,
routes: [
{ key: '1', title: 'First' },
{ key: '2', title: 'Second' },
],
};
_handleChangeTab = index => this.setState({ index });
_renderHeader = props => <TabBar {...props} />;
_renderScene = SceneMap({
'1': FirstRoute,
'2': SecondRoute,
});
render() {
return (
<TabViewAnimated
style={styles.container}
navigationState={this.state}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
onRequestChangeTab={this._handleChangeTab}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
listMahasiswa.js
import React from 'react';
import {
AppRegistry,
Text,View,Button, ListView, Image, StyleSheet
} from 'react-native';
var URL="http://www.rey1024.com/api/getListMahasiswa.php";
export default class ListMahasiswa extends React.Component{
constructor(props){
super(props);
var ds = new
ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state={
dataSource: ds,
};
}
AmbilDataMahasiswa() {
fetch(URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows
(responseData),
});
}) .done();
}
render(){
this.AmbilDataMahasiswa();
return(
<View style={styles.mainContainer}>
<Text>Daftar Mahasiswa</Text>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
</View>
);
}
renderRow(record){
return(
<View style={styles.row} >
<Text>{record.nim} {record.nama}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
mainContainer :{
flex:1,
backgroundColor:'#fff'
},
row :{
borderColor: '#f1f1f1',
borderBottomWidth: 1,
flexDirection: 'row',
marginLeft: 10,
marginRight: 10,
paddingTop: 20,
},
})
Have any solution? Thank you
ListMahasiswa in the following line is not a valid React element.
const FirstRoute = () => ListMahasiswa;
Try using jsx syntax instead:
const FirstRoute = () => <ListMahasiswa />;