Reputation: 21
I'm fairly new to react native and redux and was trying to render the library title from a JSON file in a flat list using redux, but my FlatList
component does not render anything on the screen.
here's my code :
LibraryList.js
import React, { Component } from "react";
import { FlatList } from "react-native";
import { connect } from "react-redux";
import ListItem from "./ListItem";
class LibraryList extends Component {
renderItem(library) {
return <ListItem library={library} />;
}
render() {
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={library => library.id}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
ListItem.js
import React, { Component } from "react";
import { Text } from "react-native";
import { CardSection } from "./common";
class ListItem extends Component {
render() {
return (
<CardSection>
<Text>{this.props.library.title}</Text>
</CardSection>
);
}
}
export default ListItem;
App.js
import React from "react";
import { View } from "react-native";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducers from "./reducers";
import { Header } from "./components/common";
import LibraryList from "./components/LibraryList";
const App = () => {
return (
<Provider store={createStore(reducers)}>
<View>
<Header headerText="Tech Stack" />
<LibraryList />
</View>
</Provider>
);
};
export default App;
The JSON file is like
[
{
"id": '' ,
"title": '' ,
"description":''
},
{
"id":'' ,
"title":'' ,
"description":''
}
]
I read some solutions for this suggesting changing the renderItem
function to something like this
renderItem = ({ library }) => <ListItem library={library} />
still does not work. Can someone help me with this problem?
Thanks.
Upvotes: 2
Views: 700
Reputation: 4631
You have to make your renderItem
as an arrow function. Otherwise you have to bind your function inside constructor in order to access function as renderItem={this.renderItem}
.
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import ListItem from './ListItem';
class LibraryList extends Component {
renderItem = ({ item }) => {
return <ListItem library={item} />
}
render() {
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={library => library.id}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
or you can call your renderItem
as an arrow function inside render like below
renderItem={(item) => this.renderItem(item)}
but using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison.
Hope this helps you. Feel free for doubts.
Upvotes: 2
Reputation: 1938
You have several approaches to your problem.
Firstly your renderItem should be binded, so either do this
renderItem = (library) => {
or this
renderItem={this.renderItem.bind(this)}
besides the binding problem, flatlist prop renderItem will return to your function an object with this structure
{ item, index }
so in reality your renderItem should be like this
renderItem({ item }){
return <ListItem library={item} />;
}
Upvotes: 1
Reputation: 12215
In your flatlist try thi s:
<FlatList
data={this.props.libraries}
renderItem={({item, index}) => {
this.renderItems(item); // change this name to renderItems so that it doesnt clash with flatlist default renderItem
}}
/>
Hope it helps. feel free for doubts
Upvotes: 1