nativebase tabs dynamic tab flickering - react-native

I am using nativebase and dynamic tab rendering flickering.
<Tabs renderTabBar={() => <ScrollableTab />}>
this.state.ifA ?
{<Tab>
<Text>A</Text>
</Tab>: null}
{this.state.ifB ?
<Tab>
<Text>B</Text>
</Tab>: null}
<Tabs>
Like this i have around 7 tab in tabs component which is render dynamically whenever get response from service.
Many times tabs flickering. Anyone have solution for this.

There are two props initialPage and page. Give an index of the tab that you want to render initially in these props. For example you want to render first tab at initially then :
<Tabs renderTabBar={() => <ScrollableTab />} initialPage={0} page={0}>
{ this.state.ifA ? (
<Tab>
<Text>A</Text>
</Tab>
) : null }
{ this.state.ifB ? (
<Tab>
<Text>B</Text>
</Tab>
) : null }
</Tabs>

Related

React native List footer component not rendering(funtion component)

I am trying to achieve pagination for infinite scrolling in react native. When loading, I want to render the loading spinner at the bottom of the Flat list component. (Note: I'm using Expo for this app)
const renderFooter = () => {
if (!category.loading) return null;
return (
<View style={spinnerStyles.container}>
<ActivityIndicator animating size="large" color="#0000ff" />
</View>
);
};
return (
<View style={styles.container}>
<FlatList
columnWrapperStyle={{ justifyContent: "space-between" }}
numColumns={2}
data={category.data}
renderItem={categoryItem}
keyExtractor={(item) => item._id + item.sub_category}
onEndReachedThreshold={0}
listFooterComponent={renderFooter}
onEndReached={() => loadMore()}
/>
</View>
);
The loading spinner not correctly working with the flat list footer.
Has anyone run into this issue before, or does anyone have a solution?
Sorry, it's my simple syntax error. It's actually ListFooterComponent not listFooterComponent. Now it's working fine, Thank you.
Instead of calling the refrence, call the function. It should look something like this.
ListFooterComponent={renderFooter()}

Using Animated.timing() API in React Native to slide in/out content

I have a screen in my React Native app that show/hide content based on some toggle buttons using Hooks. Everything is working fine but I'd like to improve the UI and add some animation to slide in the new content and slide out the old one.
Here's my code...
const [activeSwitch, setActiveSwitch] = useState(0);
...
return (
<Scrollview>
{activeSwitch === 1 ? (
<View>
<Text>SCREEN 1</Text>
</View>
) : null}
{activeSwitch === 2 ? (
<View>
<Text>SCREEN 2</Text>
</View>
) : null}
{activeSwitch === 3 ? (
<View>
<Text>SCREEN 3</Text>
</View>
) : null}
</Scrollview>
)}
I'm setting the state using setActiveSwitch() based on which button I click.
I've never worked with the Animation API before and tried to look at the documentation here but could not make it to work. Any help would be appreciated.

createMaterialTopTabNavigator inside ScrollView with dynamic height

Is there any way to create something like a ScrollView with dynamic height?
Details on what we're trying to do:
We created a Top Tab Bar (using createMaterialTopTabNavigator) within a ScrollView. Everything works fine, except the height of the ScrollView. Let's assume there are 3 tab screens with different heights: TabScreen1: 800, TabScreen2: 400, TabScreen3: 300... At rendering, the ScrollView takes the greatest height, and when Tab2 or 3 is selected, the height of our ScrollView remains at 800, so there is empty space for scrolling in Tab2 and 3.
As I promised, here is how we solved it.
In your class where you have your ScrollView you need a state like
const [activeTab, setActiveTab] = useState('tab1') //your default (first) tab
Later, you want to change that state every time you change tab:
<TabsStack.Screen
name={'tab1'}
component={
activeTab === 'tab1' ? Tab1Screen : DefaultScreen
}
listeners={{ focus: () => setActiveTab('tab1') }}
/>
Now every time a tab is unselected or rather not focused it will show DefaultScreen which is an empty view and has no height like:
const DefaultScreen = () => (
<Box
flex={1}
py={20}
alignItems="center"
justifyContent="center"
bg="background"
>
<ActivityIndicator size="large" color="white" animating />
</Box>
)
In my case (see question above), every time I switch from Tab1.1.1 to Tab1.1.2, Tab1.1.1 will change to DefaultScreen
Try something like this,
Fix the height of the parent widget to the maximum screen height you want that Tab Navigator to have.
<ListView or ScrollView>
<View style={{height: (width)/(0.8)}} >
<Tab.Navigator tabBar={(props) => <TabBar {...props} />}>
<Tab.Screen name="T1" component={T1} />
<Tab.Screen name="T2" component={T2} />
<Tab.Screen name="T3" component={T3} />
</Tab.Navigator>
</View>
</ ListView or ScrollView>
And for tabs do Something like this
T1 ->
<View style={styles.container}>
<ScrollView nestedScrollEnabled={true}>
<FlatList
numColumns={3}
data={allMedia}
keyExtractor={(item) => item.id}
listKey={(post) => `${post.id}D`}
renderItem={({ item }) => (Anything)}
scrollEnabled ={false}
/>
</ScrollView>
</View>
Remember to disable the scroll view Inside the FlatList of tabs and wrap with a ScrollView with nestedScrollEnabled={true}
Use this contentContainerStyle={{flex: 1}} inside scroll view
<ScrollView contentContainerStyle={{flex: 1}}>
...
// your tab
</ScrollView>
There is no need to put TabNavigator inside ScrollView. Put ScrollView inside of each TabScreen instead
Answering your question: if your ScrollView is the same height as the content then it doesn't scroll. You are probably talking about height of a contentContainer of a ScrollView. And the only wayto set it dynamically is to use onLayout to measure content height of currently selected tab, save this number to state and apply it as a height of in contentContainerStyle prop of a ScrollView. I don't recommend hacking it this way unless absolutely necessary though

Flatlist inside tabs not renedering properly

I am using tabs component from nativebase.io .
I want to display flatlist in one tab.
In that flatlist srcolling is not working properly lastitems are not dispaying.
Here is my code
<Tabs>
<Tab>
<FlatList
data={this.state.notes}
renderItem={({ item, index }) =>
<View>{item.note}</View>
}
keyExtractor={(item, index) => index.toString()}
extraData={this.state.notes}
ListEmptyComponent={<ErrorMessage />}
/>
</Tab>
</Tabs>
Put Flatlist inside a View with the view's style having flex:1. If it does not work add marginBottom to flatlist
<View style={{flex:1}}>
</View>
Wrapping it in the native base Content component, with the following style, worked for me (beware not to wrap Tab inside Content, that was my mistake):
<Tabs>
<Tab>
<Content style={{flex: 1}} contentContainerStyle={{flex: 1}}>
// your FlatList here
</Content>
</Tab>
</Tabs>

onEndReached in Flatlist issue

If I enclose the flatlist in a View then my onEndReached triggers infinitely if I remove the enclosing View onEndReached is not triggered at all.
render() {
return (
<Root>
<Container>
<Content>
<View>
{this.state.listView && (
<FlatList
data={this.state.variants}
keyExtractor={this._keyExtractor}
onEndReachedThreshold={0.5}
onEndReached={({ distanceFromEnd }) => {
console.log(
"on end reached ",
distanceFromEnd
);
this.loadMore();
}}
numColumns={1}
renderItem={({ item, index }) => (
<CatalogRow
item={item}
in_wishlist={this.state.in_wishlist}
toggleWishlist={() =>
this.toggleWishlist(item.title)
}
listView={this.state.listView}
/>
)}
/>
)}
</View>
</Content>
</Container>
</Root>
);
}
And my distanceFromEnd takes values like 0 , 960,1200 when it is trigerred. What does it indicate?
I'm using react-native 0.47.2
I have same problem with react-native 0.50.3
<Flatlist> must not be used in a <ScrollView> if you want to use onEndReached because Flatlist can not found the height.
Use a <View> instead
It was because of the enclosing <Content> tag. Sometimes embedding react-native tags with native-base tags causes such issues. I replaced the content and container tag with View tags and now it works fine.
I have same problem with RN 0.52
That look like because Flatlist can not found the heigh. So he can not find the end of list.
Fix by wrap your flatlist by a View with flex=1
<View style={{flex: 1}} > <Flatlist /> <View>
I would use it like this:
handleMore = () => {
// fetch more here
};
<FlatList
onEndReached={this.handleMore}
/>