when I'm trying to insert Image into View I get this error
View config not found for name ""
renderCategory = (category)=>{
const { Id, Image, Name } = category.item
const { button, image_category, text_category} = style;
return(
<TouchableOpacity style={style.button} onPress={()=>{console.log(Id)}}>
<View style={{flex:1}}>
//here the problem
<Image style={image_category} source={{uri:'https://picsum.photos/150/150'}} /> // when I remove it, it works fine.
<Text>{Name}</Text>
</View>
</TouchableOpacity>
)
}
render() {
const { container } = style;
return (
<View style={container}>
<FlatList style={{margin:5}}
data={this.state.second_categories}
numColumns={3}
keyExtractor={(item, index) => item.id }
renderItem={this.renderCategory}
/>
</View>
)
}
I looked in other post in stackoverflow but nothing solved my issue.
my styles
image_category:{
width: calcSize(width/4),
height: calcSize(width/4)
},
This issue is due to overwriting of the reserved-word Image.
const { Id, Image, Name } = category.item
The Image string being used in the below code is from category.item, and not the one from {Image} from 'react-native'
<Image style={image_category} source={{uri:'https://picsum.photos/150/150'}} />
Therefore you need to replace the Image object in your category.item object to something else, that is not a react-native reserved word to avoid conflicts.
OR
You may make a stateless component for the image and use it
TLDR
Replace the Image object in category.name to something else as it conflicts with react-native's tag Image or make a separate component for the image
I can't tell what you have in image_category but it must have width and height https://facebook.github.io/react-native/docs/image.html
Related
I get this warning when I tried using Flatlist inside View but same error occurs:
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
The component I am using FlatList inside is:
class About extends Component
{
constructor(props)
{
super(props);
this.state = {
leaders: LEADERS
};
}
render(){
const renderLeaders = ({item,index}) => {
return(
<ListItem
key = {index}
title = {item.name}
subtitle = {item.description}
hideChevron = {true}
leftAvatar = {{ source: require('./images/alberto.png') }}
/>
);
};
return(
<ScrollView>
<History />
<Card title = "Corporate Leadership">
<FlatList
data = {this.state.leaders}
renderItem = {renderLeaders}
keyExtractor = {item => item.id.toString()}
/>
</Card>
</ScrollView>
);
}
}
And can I use leader in place of item here? I tried using it but there was an error.
one way to hack this would be to use react-native-gesture-handler flatlist
it will sort of take over your parenting ScrollView if you absolutely need to have nested scrollers, at least that worked for me when i had this same problem.
As per second part, without delving too deep of what is what, try reading this https://www.barrymichaeldoyle.com/destructuring/#:~:text=Renaming%20Variables%20while%20Destructuring&text=In%20order%20to%20rename%20a,rename%20the%20destructured%20variable%20to or google any other theory on 'destructuring renaming'
if you absolutely need to rename 'item'.
I am trying to make a multiple choice test with a few questions using React Native package 'react-native-app-intro-slider'. The problem was that this package was not rerendering the items when something changes, state for example. I found a similar or refactored package called 'react-native-app-intro-slider-rerender-on-prop-change' that did the same thing but rerendered items on a state change. But the problem is that it does not render the Done button at last slide.
The last package i used was this :
import AppIntroSlider from 'react-native-app-intro-slider-rerender-on-prop-change';
The render method for the 'MCTContainer' (Multiple Choice Container) class is :
render() {
if (this.state.showRealApp) {
this.props.navigation.navigate('TopicGroupDetails', { topicGroup: this.state.topicGroup });
return null;
} else {
const questions = this.state.questions;
return (
<AppIntroSlider
renderItem={this._renderItem}
slides={questions}
onDone={this._onDone}
onSkip={this._onDone}
activeDotStyle={{ backgroundColor: '#039BE5' }}
showPrevButton
showNextButton
showSkipButton
showDoneButton
renderPrevButton={this._renderPrevButton}
renderNextButton={this._renderNextButton}
renderSkipButton={this._renderSkipButton}
renderDoneButton={this._renderDoneButton}
/>
)
}
}
and its renderDoneButton method is like following :
_renderDoneButton = () => {
return (
<View style={styles.buttonCircle}>
<Icon
name="check"
color="#039BE5"
size={24}
style={{ backgroundColor: 'transparent' }}
/>
</View>
);
};
This is actually the same, exactly the same as I used for the component 'SliderComponent' where I show tutorial introductory text in multiple slides. It renders the 'done' button fine. But the only differenence is that I used package 'react-native-app-intro-slider' there, not 'react-native-app-intro-slider-rerender-on-prop-change'.
Please help me if someone has encountered such a problem. Thanx in advance ...
I finally solved it.
I just added a condition on "renderItem" function of the "AppIntroSlider", that checks whether it is the last slide. If it is it renders a button that calls "AppIntroSlider"-s "_onDone" method that completes the slide show.
_renderItem = ({item}) => {
return(
{
(this.state.isLastSlide) ?
(
<TouchableHighlight
onPress={this._onDone}
>
<View>
<Text>
COMPLETE SLIDE SHOW
</Text>
<Icon
name="check"
color="white"
size={24}
/>
</View>
</TouchableHighlight>
) :
(<View></View>)
}
)
}
Currently, I'm having a problem with FlatList.
I have a component to render a list book.
By design, the header's width is the width of the screen and the body will be padding left and right 10px.
So I used contentContainerStyle={{paddingHorizontal: 10}}.
But The result is that the header and body are 10px padding left and right.
Please suggest a way to resolve it. Sorry for my bad English!!
Update: I'm so sorry for not describing my problem thoroughly.
In main.tsx
...
public render() {
return (
<FlatList
key...
data={..}
renderItem={this.renderItems}
ListHeaderComponent={this.renderHeader}
contentContainerStyle={styles.contentStyle}
/>
);
}
private renderHeader = () => {
return (
<View style={style.header}
//TODO something ...
</View>
);
}
private renderItems: ListRenderItem<IBook> = ({ item: {bookId} }) => bookId ?
(
<BookGridCell
title={...}
image={...}
//TODO more..
/>
) : <View style={styles.emptyBox} />
}
At renderItems, I called a component BookGridCell. In this component, the design of a book is set up. So if I directly add style inside renderItems, each book will have a left and right margin of 10px, not the entire body.
When use contentContainerStyle
with contenContainerStyle
When directly add style inside renderItems
with not use contentContainerStyle
Give a style to your body.
style={styles.bodyContainer}
and then inside StyleSheet add property.
const styles = StyleSheet.create({
bodyContainer: {
paddingHorizontal: 10
},
This is the correct way or
you can directly add padding inside your View.
style={{ paddingHorizontal: 10 }}
I have SectionLists inside a horizontal FlatList (react-native-snap-carousel). Each SectionList item represents an entry in a timeline. Some of the items are just text and others also have an image.
While scrolling, every time an image is visible on the screen, the fps drop to less than 10. If I simply comment the <Image> tag so that no image is rendered, the fps go up to 50>fps.
The app on the left has images, the app on the right has <Image /> component commented.
I only tested the app on Android.
Any explanation why the fps drop when an image is displayed?
renderItem:
render() {
const {
containerStyle,
hourStyle,
hourTextStyle,
contentStyle,
iconDashesStyle,
titleText,
descriptionText,
notesText
} = styles;
const activity = this.props.item;
const { type, category, date, note } = activity;
return (
<View style={containerStyle}>
<View style={hourStyle} >
<Text style={hourTextStyle}>
{moment(date).format('HH:mm')}
</Text>
</View>
<View style={iconDashesStyle}>
{this.renderIcons()}
{this.renderDashes()}
</View>
<View style={contentStyle}>
<Text style={titleText}>{getActivityName(type, category).toUpperCase()}</Text>
<Text style={descriptionText}>{getActivityDescription(activity)}</Text>
<Text style={notesText}>{note}</Text>
{this.renderImage()}
</View>
</View>
);
}
renderImage function:
renderImage() {
const { type } = this.props.item;
if (type === ID_SHARE_MOMENT && this.props.image) {
const { uri, ratio } = this.props.image;
return (
<View
ref={r => (this.imgRef = r)}
style={[styles.momentImgContainer, { aspectRatio: ratio }]}
collapsable={false}
>
<TouchableOpacity onPress={this.onPressImage}>
<Image
style={styles.momentImg}
source={{ uri }}
resizeMode='cover'
/>
</TouchableOpacity>
</View>
);
}
}
The second app without images has the renderImage as follows:
<TouchableOpacity onPress={this.onPressImage}>
{ /*
<Image
style={styles.momentImg}
source={{ uri }}
resizeMode='cover'
/>
*/ }
</TouchableOpacity>
Edit 1
While trying to improve the performance of my app, I followed this link of Adam Stanford on medium, which suggested to load static assets directly from the app package (images included via Xcode asset catalogs or in the Android drawable folder).
I started with the background image of the entry screen that precedes the screen shown above, which only has a background image, a logo, and a spinner:
Only by doing this in this first image, look what happened:
The fps went up to 40+ even when rendering the images in the timeline. However, I do not understand the relation...
I'm building a header and I want to hide the header content UNTIL the user scrolls down to the certain point.
(My Approach)
Get scrollY position (How much did user scroll vertically from top?)
if scrollY is greater than 50
show the header name.
Here is render() method. I manually built header. I'm getting scrollY value and set it to this.state.scrollY
<View style={{flex:1}}>
<View style={styles.header}>
{this._renderHeader(profile.username)}
</View>
<ScrollView style={styles.root}
onScroll={(event)=>{this.setState({scrollY: event.nativeEvent.contentOffset.y})}}>
// setting this.state.scrollY for scroll Y position
...
Here is _renderHeader function. (rendering header)
_renderHeader = (username) => {
return (
<View style={styles.headerLayout}>
<View rkCardHeader style={styles.left}>
...
<View style={{justifyContent: 'center'}}>
{this._renderUsername(username)}
// I want to show this string ONLY IF user
// scrolls down the window to the certain point.
</View>
....
</View>
);
}
(Here is the problem) This doesn't render only or it doesn't trigger _renderUsername.
_renderUsername = (username) => {
let show = (this.state.scrollY > 50) ? true : false;
if(show) {
return (
<RkText rkType='header3'>{username}</RkText>
);
} else {
return <View />
}
}
You can keep a track of scrollY in redux store and map it to the header component.
While rendering the header component use ternary expression to decide whether to render or not.
For example -
(From the store you will get the value this.props.scrollY)
render() {
return (
{this.props.scrollY > 50 ? <AppHeader /> : ""}
);
}