FlatList is not rendereing properly - javascript

I am implementing FlatList and it is not giving the desired rendring output.
Here is my Code:
App.js
import React from 'react';
import Main from './components/MainComponent';
export default class App extends React.Component {
render() {
return (
<Main />
);
}
}
MainComponent.js
import React, { Component } from 'react';
import Menu from './MenuComponent';
import { DISHES } from '../shared/dishes';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
dishes: DISHES
};
}
render() {
return (
<Menu dishes={this.state.dishes} />
);
}
}
export default Main;
MenuComponent.js
import React from 'react';
import { View, FlatList } from 'react-native';
import { ListItem } from 'react-native-elements';
function Menu(props) {
const renderMenuItem = ({item, index}) => {
return (
<ListItem
key={index}
title={item.name}
subtitle={item.description}
hideChevron={true}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
);
};
return (
<FlatList
data={props.dishes}
renderItem={renderMenuItem}
keyExtractor={item => item.id.toString()}
/>
);
}
export default Menu;
Bug:
I am getting the following output which is not desired.
result image
Desired Output:
I want output like image below. How can I achieve it?
Desired output image

are you sure that the problem is with flatlist ? , you are seeing a list , and that means that it's working. So... the problem is with ListItem component, according to this and this , the ListItem doesn´t have hideChevron property [in the latest version], try updating the module ;), deleting hideChevron [wich hides the image], or putting chevron ={true} , because you want to show the image like the desired output

you should render your list accordingly
just define your view
const renderMenuItem = ({item, index}) => {
return (
<View style={{...}}>
<Text style={styles.title}>
{item.name}
<Text>
<Text style={styles.description}>
{item.description}
<Text>
<Image source: require('./images/uthappizza.png')/>
</View>
);
};

Related

React Native - Element type is invalid

I'm trying to do a React Native app using Expo cli. However when I'm testing it I get error. What should I do to solve the problem?
Error: Element type is invalid: expected a string (for built-in
components) or a class/function (for composite components) but got:
undefined. You likely forgot to export your component from the file
it's defined in, or you might have mixed up default and named imports.
Check the render method of FetchExample.
import React, {Component} from 'react';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { Flatlist, ActivityIndicator, View, TouchableWithoutFeedback } from 'react-native';
import styles from './styles'
import Content from './Components/content'
import ContentDonate from './Components/contentdonate';
import Details from './Components/details';
import Header from './Components/header';
import Footer from './Components/footer'
class FetchExample extends React.Component {
static navigationOptions = {
title: 'Database',
};
constructor(props){
super(props);
this.state ={isLoading: true}
}
actionOnRow(item) {
this.props.navigation.navigate('Details', {item});
}
componentDidMount(){
return fetch('https://mocki.io/v1/01994c7b-9eb6-4fe4-b399-1bc5992d1a10')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
},
);
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View>
<ActivityIndicator/>
</View>
)
}
return(
<View style={styles.background}>
<View style={styles.container}>
<Flatlist
data ={this.state.dataSource}
renderItem={({item}) =>
<TouchableWithoutFeedback onPress ={ () => this.actionOnRow(item)}>
<Text style = {styles.listTextStyle}>{item.Name}</Text>
</TouchableWithoutFeedback>
}
keyExtractor={item => item.Id.toString()}
/>
</View>
</View>
);
}
}
//NAVIGATION
class HomePage extends Component {
render(){
return (
<View style = {styles.container}>
<Header/>
<Content/>
<Footer/>
</View>
);
}
}
class DonatePage extends Component {
render(){
return (
<View style = {styles.container}>
<Header/>
<ContentDonate/>
<Footer/>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomePage,
Donate: DonatePage,
Details: Details,
Database: FetchExample
},
{
initialRouteName: 'Home',
}
);
export default createAppContainer(AppNavigator);
Syntax Error: Flatlist, change it to FlatList.
Id field not found in keyExtractor, change keyExtractor={(item) => item.Id.toString()} to keyExtractor={(item) => item._id} (_id is already a string)

Why can't I type in my react-native SearchBar?

When I type, nothing shows up in the search bar, but it knows that I'm typing (from the print statements in my updateSearch function). From my understanding of the react-native searchBar, there isn't even anything I need to do for text to be showing up there, so I really have no idea how I could have screwed this up. This is a part of a larger project.. but I'm praying this issue doesn't have anything to do with the rest of it.
import React, { Component } from "react";
import {
View,
Text,
FlatList,
ActivityIndicator,
SafeAreaView,
StyleSheet
} from "react-native";
import Header from "../components/Header";
import { SearchBar, List, ListItem } from 'react-native-elements';
export default class Search extends React.Component {
constructor(props) {
super(props);
this.state = {
query: "",
data: []
};
}
renderHeader = () => {
return (
<SearchBar
placeholder="Type Here..."
onChangeText={this.updateSearch}
value={this.state.query}
lightTheme={true}
/>
);
}
updateSearch = text => {
console.log("text", text);
const formattedSearch = text.toLowerCase();
this.setState({ query: formattedSearch });
console.log("text", this.state.query);
};
render() {
return (
<SafeAreaView style={styles.container}>
<Header text={"Search"} />
<FlatList
ListHeaderComponent={this.renderHeader}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Expo.Constants.statusBarHeight
}
});
If you want to update your UI with render, you have to update your state.
In your FlatList component, you don't update state. So it never renders again.
You have to use state in your FlatList.
render() {
return (
<SafeAreaView style={styles.container}>
<Header text={"Search"} />
<FlatList
ListHeaderComponent={this.renderHeader}
AnyProp={this.state.anyState}
/>
</SafeAreaView>
);
}
The problem is with the ListHeaderComponent.
I did a demo project to see what was happening :
import React, { Component } from 'react'
import { SafeAreaView, FlatList, TextInput } from 'react-native'
export default class Test extends Component {
constructor(props){
super(props)
this.state={value:""}
}
renderHeader = () =>{
console.log("rendering")
return (<TextInput style={{backgroundColor:"green"}}value={this.state.value} placeholder={"Placeholder"}onChangeText={(text)=> this.setState({value : text})}></TextInput>)
}
render() {
console.log(this.state.value) //Logs the value
return (
<SafeAreaView style={{flex:1}}>
<FlatList
ListHeaderComponent={this.renderHeader}
/>
</SafeAreaView>
)
}
}
It looks like once the component has rendered, it does not update anymore. The log inside the render does actually update, but the component do not re-render himself (probably cause the FlatList do not update the ListHeaderComponent once it is done with the first render)
I would suggest to move the SearchBar above the FlatList and enclose everything inside a ScrollView.
EDIT,
To confirm that it was actually updating, i created another TextInput and put it outside the FlatList, and it worked normally:
import React, { Component } from 'react'
import { SafeAreaView, FlatList, TextInput } from 'react-native'
export default class Test extends Component {
constructor(props){
super(props)
this.state={value:""}
}
renderHeader = () =>{
console.log("rendering")
return (<TextInput style={{backgroundColor:"green"}}value={this.state.value} placeholder={"Placeholder"}onChangeText={(text)=> this.setState({value : text})}></TextInput>)
}
render() {
console.log(this.state.value) //Logs the value
return (
<SafeAreaView style={{flex:1}}>
<TextInput style={{backgroundColor:"red"}}value={this.state.value} placeholder={"Placeholder"}onChangeText={(text)=> this.setState({value : text})}></TextInput>
<FlatList
ListHeaderComponent={this.renderHeader}
/>
</SafeAreaView>
)
}
}

REACT - Error to render component

I have the code below and it not work
import React, { Component } from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default class Splash extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.chars}>
<SeparateText value='AFEW' />
</View>
</View>
);
}
}
class SeparateText extends Component {
render() {
return ({
this.props.value.split('')
.map(char => <Text>{char}</Text>)
});
}
}
In execution, the server shows the error below:
My final objective is do somethink like this:
And I do it! Using the code below I do what I am trying do, but I need some code to show that screen using map and react. I try from many forms, but unsucessfull.
import React, { Component } from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default class Splash extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.splashChars}>
<SplashChar value='A' />
<SplashChar value='F' />
<SplashChar value='E' />
<SplashChar value='W' />
</View>
<View style={styles.splashText}>
<Text></Text>
</View>
</View>
);
}
}
class SplashChar extends Component {
render() {
return (
<Text style={styles.splashChar}>{this.props.value}</Text>
);
}
}
You are missing to enclose the JSX inside of the View.
class SeparateText extends Component {
render() {
return (
<View>
{this
.props
.value
.split('')
.map(char => <Text>{char}</Text>)
}
</View>
)
}
}
You need a root enclose tag.
return (
<View>{this.props.value.split('').map(char => <Text>{char}</Text>)</View>
);

how to pass properties to a react-native component inside a tab navigator?

I have the following code:
import React, { Component } from 'react';
import {TabNavigator} from 'react-navigation';
import {Button,FlatList,Text,View} from 'react-native';
class Recent extends Component<{}> {
getData() {
return ["Locked in room","Fell on the floor", "Need help with Stairs"];
}
render() {
let {navigate} = this.props.navigation;
console.log(this.props.user); // this line gives me undefined
return (
<FlatList
style={{flex:1,width:"100%"}}
data={this.getData()}
keyExtractor={(item, index) => index}
renderItem={({item}) => <Text onPress={()=>navigate("NextPage",{user:this.props.user})}>{item}</Text>}
/>
);
}
}
const RequestRouter = TabNavigator({
Recent1: {screen: Recent},
Recent2:{screen:Recent}
}
);
export default class App extends Component<{}> {
render() {
let {navigate} = this.props.navigation;
const user = this.props.navigation.state.params.user;
return (
<View style={{flex:1,flexDirection:"column"}}>
<Button onPress={()=>navigate("NextPage",{user:user})}
title="Go"
accessibilityLabel="Go"
/>
<View style={{width:"100%",flex:6,flexDirection:"column"}}>
<RequestRouter user={user} />
</View>
</View>
);
}
}
The issue I'm having is that the console.log(this.props.user); inside the class Recent extends Component gives me an undefined. This is because I don't know how to properly pass the user variable in the App.render() into the Recent.render(), since there is a TabNavigator that routes requests to the Recent class.
How do I pass the user variable from App.render() into Recent?
You can use screenProps to pass props to child component inside TabNavigator like this:
<RequestRouter screenProps={user} />
You can access it in child component by this.props.screenProps.user

undefined is not a function (evaluating '_this2.closeDrawer()') error in react native app

I am beginner of react native. I am using NativeBase Components for designing. When I use drawer app giving this error
undefined is not a function (evaluating '_this2.closeDrawer()')
This is screenshot of error
Drawer Code is here
import React, { Component } from 'react';
import { Drawer } from 'native-base';
import SideBar from './sidebar';
import Signup from './signup';
import { View } from 'react-native';
export default class NativeDrawer extends Component {
render() {
closeDrawer = () => {
this.drawer._root.close()
};
openDrawer = () => {
this.drawer._root.open()
};
return (
<View>
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} />}
onClose={() => this.closeDrawer()} >
</Drawer>
</View>
);
}
}
SideBar code is here
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default class SideBar extends Component {
render() {
return (
<View style={styles.container} >
<Text>
Hello World
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Other NativeBase components are working but Drawer is giving an error
You are setting the prop onClose for your <Drawer> component by using a reference to this.closeDrawer.
This will look for the definition of closerDrawer on your component but you have defined it within your render method.
Defining closeDrawer in the scope of the Component should fix your issue (N.B. I've also moved openDrawer out of render as well):
export default class NativeDrawer extends Component {
// Moved outside of render:
closeDrawer = () => {
this.drawer._root.close()
};
openDrawer = () => {
this.drawer._root.open()
};
render() {
return (
<View>
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} />}
onClose={() => this.closeDrawer()} >
</Drawer>
</View>
);
}
}
Most simple: just remove the "this." in front of closeDrawer()
I'm running the same example code and that fixed it for me!

Categories

Resources