React Native Flatlist inside Wrapper Component break the scolling - components

Hello i have a Problem with my wrapper component. If i put inside the Flatlist component the scrolling doesn't work anymore. I try to pur everywhere flex:1 (on flatlist, on the wrapper itself) but no changes still broken.
What is my mistake?
I expected the normal scroll behavior.
import React from 'react';
import { KeyboardAvoidingView, TouchableWithoutFeedback, Keyboard, Platform } from 'react-native';
const KeyboardAvoidingViewWrapper = ({ children, keyboardOffset }) => {
const additionalOffset = Platform.OS === 'ios' ? 0 : 17;
return (
<KeyboardAvoidingView
keyboardVerticalOffset={keyboardOffset ? keyboardOffset + additionalOffset : 65 + additionalOffset}
behavior={Platform.OS == "ios" ? "padding" : "height"}
style={{ flex: 1, }}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
{children}
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
)
}
export default KeyboardAvoidingViewWrapper;
In the Screen:
<KeyboardAvoidingViewWrapper>
<View style={{ flex: 1 }}>
<FlatList
data={data}
.....
/>
</View>
</KeyboardAvoidingViewWrapper>
Any help is more than appreciate. Thank you.

try giving 'position' to behavior property to your KeyboardAvoidingView.
<KeyboardAvoidingView behavior='position'>

Related

Error: `useTheme` must be used within `NativeBaseConfigProvider`

In my project I experienced the above error
The error explanation :
This error is located at:
in Container
in ProductContainer (created by App)
in RCTView (created by View)
in View (created by App)
in App (created by ExpoRoot)
in ExpoRoot
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
ProductContainer.js:
import React, { useState, useEffect } from 'react'
import { View, StyleSheet, ActivityIndicator, FlatList, Text} from 'react-native'
import { Container, Header, Icon, Item, Input, Text } from 'native-base';
import ProductList from './ProductList';
const data = require('../../assets/data/products.json');
const ProductContainer = () => {
const [products, setProducts ] = useState([]);
useEffect(() => {
setProducts(data);
return () => {
setProducts([])
}
}, [])
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}
})
return (
<Container>
<Header searchBar rounded>
</Header>
<View style={styles.container}>
<Text>Product Container</Text>
<View style={styles.listContainer}>
<FlatList
data={products}
numColumns={2}
renderItem={({item}) => <ProductList
key={item.brand}
item={item}/>}
keyExtractor={item => item.brand}
/>
</View>
</View>
</Container>
)
}
export default ProductContainer;
I managed to solve this error from this github issue: https://github.com/GeekyAnts/NativeBase/issues/4303.
Apparently the problem is that you need to wrap app elements in <NativeBaseProvider>.
In this example you can see how the native base provider wraps all other providers, if the <NativeBaseProvider> is not at the top, it will throw the error: useTheme must be used within `NativeBaseConfigProvider
export default function App() {
return (
<NativeBaseProvider>
<SafeAreaProvider>
<AuthProvider>
<Navigation colorScheme={colorScheme} />
<StatusBar />
</AuthProvider>
</SafeAreaProvider>
</NativeBaseProvider>
);
}
<Container>
<Header searchBar rounded>
</Header>
<View style={styles.container}>
<Text>Product Container</Text>
<View style={styles.listContainer}>
<FlatList
data={products}
numColumns={2}
renderItem={({item}) => <ProductList
key={item.brand}
item={item}/>}
keyExtractor={item => item.brand}
/>
</View>
</View>
</Container>
wrap all these Container tag and its contents inside...
If the issue is happening in Testing you can simply pass initialWindowMetrics to NativeBaseProvider in your tests.
const inset = {
frame: { x: 0, y: 0, width: 0, height: 0 },
insets: { top: 0, left: 0, right: 0, bottom: 0 },
};
<NativeBaseProvider initialWindowMetrics={inset}>
{children}
</NativeBaseProvider>;

How to change sort icon in detailslist

I am using detailslist, is there a quick property to change sort icon?
I find below styles but do not know how to set it
That's not possible because sort icon is implemented directly inside DetailsColumn.base.tsx:
{column.isSorted && (
<IconComponent
className={classNames.sortIcon}
iconName={column.isSortedDescending ? 'SortDown' : 'SortUp'}
/>
)}
But if you really need that functionality you can recompose DetailsList Component. Hint:
<DetailsList
onRenderDetailsHeader={(headerProps, defaultRender) => {
return headerProps && defaultRender ? (
{defaultRender({
...headerProps,
onRenderColumnHeaderTooltip: props => {
return <TooltipHost {...props} children={/* Implementation here! */} />
}
})}
) : null;
}}
/>
Keep the same children functionality and rewrite icon render.
Codepen example for hint.
You are able to achieve what you want by doing some css trickery. In my use-case I only had to change the color. In the example below I added a background-image for setting your own icon.
<DetailsList onRenderDetailsHeader={(headerProps, defaultRender) => {
return defaultRender({
...headerProps,
styles: {
root: {
selectors: {
'.ms-DetailsHeader-cell': {
backgroundColor: '#0f238c',
color: 'white'
},
'.ms-Icon': {
color: '#0f238c',
backgroundColor: '#0f238c',
backgroundImage: decendingFilter ? 'url([PATHTOIMG1])' : 'url([PATHTOIMG2])',
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
},
},
}
}
});
}}
/>

in react native how i can change background color for every view element independent

for every view element independent when i press them without effect other views and save pressed state so next time i can find what ipressed still pressed and i can change color of other view when ipress them without lose stat of preview view
the problem is when i press one from two task the other task also change her background color
import React, { useState } from 'react';
import {
SafeAreaView,
View,
FlatList,
StyleSheet,
Text,
TouchableOpacity,
} from 'react-native';
function App() {
const [changBack,backgroundColor]=useState('green')
function changIt() {
backgroundColor('red');
}
const DATA1 = 'Task one';
const DATA2 = 'Task two';
return (
<View>
<TouchableOpacity
style={{
flex: 1,
backgroundColor:changBack,
padding: 20,
}}
onPress={changIt}>
<View>
<Text>{DATA1}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{
flex: 1,
backgroundColor:changBack,
padding: 20,
}}
onPress={changIt}>
<View>
<Text>{DATA2}</Text>
</View>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'column',
textAlign:'right',
justifyContent:'space-evenly',
},
});
export default App;
Brother I notice you passed backgroundColor on Style for <TouchableOpacity> so definitely it won't work. backgroundColor is applicable for <View> only but not for TouchableOpcacity.
Do something like this ~
<View>
<View style={{backgroundColor:changBack}}>
<TouchableOpacity onPress={changeIt}>
<View>
<Text>Heyya</Text>
</View>
</ToucableOpacity>
</View>
</View>
or this,
<View>
<TouchableOpacity onPress={changeIt}>
<View style={{backgroundColor:changBack}}>
<Text>Heyya</Text>
</View>
</ToucableOpacity>
</View>

React Native no luck with fixing my FlatList - VirtualizedList: You have a large list that is slow to update

I have been trying to fix my virtualize list issue du to too many rendering apparently...
this is happening when I go back and forth, from one item here: restaurant (restaurant screen) to the flatList with the tab bar, I have also been trying to render less items, but even when the limit is down it doesn't seems to work...
What I use
I'm using a animated bottom sheet that display the flatList on top of the mapView
what I tried
I have been looking ,and tried that out
and also that
and those issues too
I have tried to use the Hook useMemo but apparently it does work for complex stuff such as arrays, or I my config of the dependency was wrong:
const renderMemo = useMemo(() => renderItem, []) //what should be in the array? data? !isLoading ? limit ? ( the limit is change when onEndReached)
(code below)
I have tried to make a pure component of my list (renderItem)
ISSUE
I still get :
VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. Object {
"contentLength": 5148.66650390625,
"dt": 4164,
"prevDt": 2313,
}
and in this particular set up after not doing anything for a while I got that error:
_Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at [native code]:null in dispatchAction
at containers/HomeScreen.js:87:16 in fetchData
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue_
I haven't tried shouldComponentUpdate as I don't really understand it... I mean I don't know where to locate it...
where should I head now ? memo maybe?
is there a way maybe to get less render from useEffect
CODE
repo native
HomeScreen:
const renderContent = () =>
!isLoading ? (
<View style={styles.firstParentViewRenderContent}>
....
<FlatListContents
data={data}
navigation={navigation}
setLimit={setLimit}
limit={limit}
skip={skip}
setSkip={setSkip}
handleColors={handleColors}
/>
</View>
flatListContents component:
const handleLoadMore = () => {
console.trace("handleMore");
// console.log(limit);
setIsLoadingMore(true);
// if (limit > 30) setIsLoadingMore(false);
if (!isLoading) {
setLimit(limit + 10);
setIsLoadingMore(false);
}
};
// const renderMemo = useMemo(() => renderItem, []);
const renderItem = ({ item }) => {
return (
<PureCompFlatlist
item={item}
handleColors={handleColors}
navigation={navigation}
/>
);
};
return (
<FlatList
data={data}
keyExtractor={(item) => String(item.placeId)}
renderItem={renderItem}
removeClippedSubviews={true}
maxToRenderPerBatch={20}
initialNumToRender={5}
windowSize={limit}
getItemLayout={(data, index) => {
return {
length: styles.flatList.height,
offset: 25 * styles.flatList.height,
index,
};
}}
onEndReached={handleLoadMore}
onEndReachedThreshold={0.5}
// ListFooterComponent={renderFooter}
/>
PureCompFlat:
export class PureCompFlatlist extends PureComponent {
render() {
const { item, handleColors, navigation } = this.props;
return (
<TouchableOpacity
style={styles.flatList}
onPress={() =>
navigation.navigate("Restaurant", {
id: item.placeId,
name: item.name,
description: item.description,
rating: item.rating,
thumbnail: item.thumbnail,
color: handleColors(item.type),
})
}
>
<Image style={styles.flatListPic} source={{ uri: item.thumbnail }} />
<View style={styles.flatListContent}>
<View style={styles.flatListNameType}>
<Text style={styles.flatListText}>{item.name}</Text>
<Text style={styles.flatListText}>{item.type}</Text>
</View>
<Text style={styles.flatListText}>{item.rating}</Text>
<Text style={styles.flatListText} numberOfLines={2}>
{item.description}
</Text>
</View>
</TouchableOpacity>
);
}
}
thanks in advance

React-Native display image or video on mime/file type condition

i am making a gallery app using React-Native with node.js , I got a data from Node.js api, i want to display files either image or video depends on file type in a FlatList , I don't know how to write the condition for that,
{items.file_Name == 'mp4' ? Video : image }
I am trying to use the above code but i don't know how to get the file name. So please check my code
export default class HomeScreen extends React.Component {
constructor(Props) {
super(Props);
this.state = {
error: null,
Posts:[
{"id":166,"user_id":1,"description":"7th test","file_Name":[VID-WA0005.mp4"]},
{"id":10,"user_id":3,"description":" 6th test","file_Name":["10.jpg", "12.jpg"]},
{"id":9,"user_id":2,"description":" 5th test","file_Name":["9.jpg", "14.jpg"]} ],
}
}
render() {
const { Posts } = this.state
return (
<View style={styles.container}>
<View style={styles.tabContent}>
<FlatList style={styles.list}
data={this.state.Posts}
keyExtractor={(data_posts, index) => {
return data_posts.id.toString();
}}
ItemSeparatorComponent={() => {
return (
<View style={styles.separator} />
)
}}
renderItem={(post, id) => {
const items = post.item;
return (
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.title}>{items.description}</Text>
</View>
<View style={styles.cardContent}>
{items.file_Name.split('.').reverse()[0] == 'mp4' ?
<Video
source={{ uri: "http://192.168.1.2:3200/" + items.file_Name }}
style={{ width: '100%', height: 600 }}
resizeMode="cover"
paused={this.state.paused}
controls={true}
volume={this.state.volume}
muted={this.state.muted}
paused={this.state.paused}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
onProgress={this.onProgress}
/>
:
<Image style={styles.cardImage} source={{ uri: "http://192.168.1.2:3200/" + item.file_Name }} />
}
</View>
</View>
)
}}
/>
{/* Flatlist Ends*/}
</View>
</View>
);
}
}
````
I tried with condition like
````{items.file_Name.split('.').reverse()[0] == 'mp4' ? <Video /> : <image />}````
But its not working because i am unable to get the file type.
If anyone know how to get the file name and how to display either video or image please tell me .
You can use endsWith() function is used to check whether the given string ends with the characters of the specified string or not
{items.file_Name.toString().endsWith("mp4") ? Video : image }
Try this
{items.file_Name.split('.').pop() == 'mp4'?<Video /> : <image />}

Resources