Using Flatlist in react native - reactjs

How can my flatlist now showing any list, it just show blank inside some
container:
here the json Data :
{
"page": 2,
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 4,
"first_name": "Eve",
"last_name": "Holt",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
},
{
"id": 5,
"first_name": "Charles",
"last_name": "Morris",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
},
{
"id": 6,
"first_name": "Tracey",
"last_name": "Ramos",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
}
]
}
from regres.in to test the dummy data, and here my code :
class UserList extends React.Component {
state = {
apiAreLoaded: false,
};
constructor(props) {
super(props);
this.state.data = [];
}
async componentDidMount() {
// define the api
const api = create({
baseURL: 'https://reqres.in/',
headers: {
Accept: 'application/json'
}
})
// start making calls
//api.get('/api/users?page=2').then((response) => response.data).then(console.log);
//use async
const response = await api.get('/api/users?page=2');
// console.log(response.data.data);
this.setState({ apiAreLoaded: true, data: response.data });
// console.log(this.state.data);
}
render() {
if(!this.state.apiAreLoaded)
{
return <AppLoading />;
}
return(
<Container>
<Content>
<FlatList
data={this.state.data}
renderItem={({ item }) => {
console.log(data.avatar)
return(
<ListItem>
<Text>{item.id}</Text>
</ListItem>
)
}}
/>
</Content>
</Container>
);
}
}
export {UserList};
For information I am using this version :
"expo": "^27.0.1", "native-base": "^2.6.1",
"react": "^16.4.1",
"react-native": "~0.55.2"
any suggestion ?

It works now... and here how it works...
Make sure you format the api response as the doc say like this :
data={[{title: 'Title Text', key: 'item1'}, ...]}
note :
if you use https://reqres.in as dummy data make sure you get the response like this.
this.setState({ data: response.data.data });
Use Flatlist and keyExtractor here the code sample :
<FlatList
data={this.state.data}
keyExtractor={this._keyExtractor}
renderItem={({item}) =>
<Text>{item.first_name}</Text>
}
/>
See the _keyExtractor, the extractor key used to make virtualized key and here the code :
._keyExtractor = (item, index) => index.toString();

Related

React native not updates the UI after useState()

i am trying to render the nested list in react-native with express,
Initially i am updating the state with first level list, by using onPress event I am trying to update the state by nesting the that particular subList object into the appropirate list object.
here is my code
<TouchableWithoutFeedback
onPress={ async () => {
fetch(`http://192.168.64.1:3000/getTypes/${item.id}`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
.then((response) => response.json())
.then((data) => {
let changedState = [...retrivedData]
changedState.map((dataItem) => {
if(dataItem.id == item.id){
dataItem.checked = !dataItem.checked
dataItem.subCategory = data
}
})
setRetrivedData(changedState);
console.warn(retrivedData);
})
}} >
<View key={item.id}>
<View style={styles.menus} key={item.id}>
<Text style={[{ fontWeight: 'normal', color: 'black' }, styles.menuTitle]}>{item.name}</Text>
<Icon style={styles.icon} name={item.checked ? 'chevron-small-up' : 'chevron-small-down' } type='entypo' />
</View>
{item.checked &&
retrivedData.map((category) => {
if(category.categoriesId == item.id){
if(category.subCategory.length > 0)
{
category.subCategory.map((subItem) => {
return(
<View style={styles.subMenus}>
<Text style={styles.subMenu}>{subItem.name}</Text>
</View>
)
})
}
}
})
}
</View>
</TouchableWithoutFeedback>
Here is my state before update
[
{"checked": true,
"id": 1,
"name": "clothing",
"productCategoryId": 1,
},
{
"checked": false,
"id": 2,
"name": "footwear",
"productCategoryId": 1
},
...
]
Here is my code after update
[
{"checked": true,
"id": 1,
"name": "clothing",
"productCategoryId": 1,
"subCategory": [
[Object],
[Object],
[Object],
[Object],
[Object],
[Object]
]
},
{
"checked": false,
"id": 2,
"name": "footwear",
"productCategoryId": 1
},
...
]
To Update The UI You Have To Update The State using this.setState() method on the data you are trying to put on the state and this will automatically rerender the UI
I was using nested map method so it sets the state before the map method completes its process....
I have sorted out that by fetching all the while mounting ..
Thanks,

How to pass object array as props to a custom component in react native?

I have fetched some data from an API as a JSON array in componentDidMount method as below.
componentDidMount() {
return fetch('http://..someAPI../product/')
.then(res => res.json())
.then(resJson => {
this.setState({
isLoading: false,
dataSource: resJson,
});
var objects = this.state.dataSource;
for (var i = 0; i < objects.length; i++) {
console.log('Item Name: ' + objects[i].productName);
}
})
.catch(err => {
console.log(err);
});
}
In here I get console.log output as I want. Now I want to pass the array in a loop as a prop to a custom component, but it gives error.
My render method looks like this
return (
<View>
<Content>
{this.state.dataSource.map(item => {
<Product Name={item.productName} price={item.price}/>;
})}
</Content>
</View>
);
My original Json object looks like this
[
{
"category": [
"Food",
"Bread",
"Bun"
],
"_id": "1",
"productName": "Sausage bun",
"price": 70,
"details": "test product",
},
{
"category": [
"Food",
"Bread",
"Bun"
],
"_id": "2",
"productName": "Fish Pastry",
"price": 50,
"details": "test product",
}
]
I want to pass these data to display the products as a loop. How can I do this? Thank you in advance!
Since data loading is asynchronous you probably have uninitialised state.
As a safer coding practice you could something like
{this.state.dataSource && this.state.dataSource.map(item => {
return <Product Name={item.productName} price={item.price}/>;
})}
Depending on your webpack configuration , you can also use optional chaining https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
{this.state?.dataSource?.map(item => {
<Product Name={item.productName} price={item.price}/>;
})}
Also,
initialize your state
this.state = {
dataSource: []
}

How do I loop an array in React Native

The RSS feed is parsed into an array, but the promblem is, the array doesn't loop, it only shows 1 item. How do I loop my Feeds array?
This is my code, I use react-native-rss-parser (https://www.npmjs.com/package/react-native-rss-parser):
class TNScreens extends React.Component {
state = {
feed: [],
title: []
};
componentDidMount() {
return fetch("https://vnexpress.net/rss/tin-moi-nhat.rss")
.then(response => response.text())
.then(responseData => rssParser.parse(responseData))
.then(rss => {
for (let i = 0; i < rss.items.length; i++) {
this.setState(prevState => ({
...prevState,
feed: rss.items[i],
title: rss.items[i].title
}));
}
});
}
render() {
const Feeds = ([
{
pic: {uri: ''},
title: Object.keys(this.state.title).map(i => this.state.title[i])
}
]);
return (
<SafeAreaView>
<ScrollView>
<Text h2 h2Style={styles.h2Style}>
Trang nhất
</Text>
<Text h4 h4Style={styles.h4Style}>
Cập nhật siêu nhanh
</Text>
<View>
{Feeds.map(({ pic, title }) => (
<Tile
imageSrc={pic}
height={200}
activeOpacity={0.9}
title={title}
titleNumberOfLines={1}
titleStyle={styles.title}
featured
key={title}
/>
))}
</View>
</ScrollView>
</SafeAreaView>
);
}
}
export default TNScreen;
UPDATE
console.log(rss) result:
Object {
"authors": Array [],
"categories": Array [],
"copyright": undefined,
"description": "VnExpress RSS",
"image": Object {
"description": undefined,
"height": undefined,
"title": "Tin nhanh VnExpress - Đọc báo, tin tức online 24h",
"url": "https://s.vnecdn.net/vnexpress/i/v20/logos/vne_logo_rss.png",
"width": undefined,
},
"items": Array [],
"itunes": Object {
"authors": Array [],
"block": undefined,
"categories": Array [],
"complete": undefined,
"explicit": undefined,
"image": undefined,
"newFeedUrl": undefined,
"owner": Object {
"email": undefined,
"name": undefined,
},
"subtitle": undefined,
"summary": undefined,
},
"language": undefined,
"lastPublished": "Sat, 30 Nov 2019 21:28:12 +0700",
"lastUpdated": undefined,
"links": Array [
Object {
"rel": "",
"url": "https://vnexpress.net/rss/tin-moi-nhat.rss",
},
],
"title": "Tin mới nhất - VnExpress RSS",
"type": "rss-v2",
}
There is a problem in your code in for loop you are just replacing the state with one value you are not copying the previous state. You will have to
this.setState(prevState => ({
...prevState,
feed: [...prevState.feed, rss.items[i]],
title: [...prevState, rss.items[i].title]
}));
But this is not the best practice because on every iteration your render will re-render so the best practice is
const feeds = rss.items.map(item => item);
const titles = rss.items.map(item => item.title);
this.setState({ feed: feeds, title:titles });
your this.state.x only save one item, change the code to the following:
and you should also change the get Data method, please do not setState in a loop
componentDidMount() {
return fetch("https://vnexpress.net/rss/tin-moi-nhat.rss")
.then(response => response.text())
.then(responseData => rssParser.parse(responseData))
.then(rss => {
let copyRess = []
let copyTitle = []
for (let i = 0; i < rss.items.length; i++) {
copyRess.push(rss.items[i]);
copyTitle.push(rss.items[i].title)
}
this.setState(prevState => ({
...prevState,
feed: copuRess,
title: copyTitle
}));
});
}
render() {
const Feeds = []
this.state.title.map(element => {
Feeds.push({pic:"",title:element})
})
....

How to list incoming data in React Native

I want to list the data from the service I use as it is in the example. Can you help me?
My code:
import React, { Component } from "react";
export default class CustomersTab extends Component {
constructor(props) {
super(props);
this.state = {
token: "",
isLoading: true,
dataSource: null
};
}
componentWillMount() {
tokenner()
.then(responseJson => {
const token = "Bearer " + responseJson.result.token;
this.setState({ token });
fetch(
"apiurl",
{
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: token
}
}
)
.then(response => response.json())
.then(responseData => {
this.setState({
isLoading: false,
dataSource: responseData.result
});
});
})
.catch(error => console.warn(error));
}};
render() {
return (
<View>
<Text>
I WANT LİST DATA HERE
</Text>
</View> )}}
I tried to do it myself, but I could not build the loop structure. Only one data is displayed every time. What should I do?
you have to do something like this. Change id to what you want to display.
return (
<View>
<ListView
dataSource={this.state.dataSource}
renderRow={data => <Text>{data.id}</Text>}
/>
</View>
);
Please Import the View and Text from react native.
import {
Text,
View,
} from 'react-native';
constructor(props: Object) {
super(props);
this.state = {
dataSource: []
}
};
/* dataSource = [
{ "id": "1", "title": "Star Wars", "releaseYear": "1977" },
{ "id": "2", "title": "Back to the Future", "releaseYear": "1985" },
{ "id": "3", "title": "The Matrix", "releaseYear": "1999" },
{ "id": "4", "title": "Inception", "releaseYear": "2010" },
{ "id": "5", "title": "Interstellar", "releaseYear": "2014" }
]
*/
renderMovieList(){
return this.state.dataSource.map((movie, index) =>
<View
key={movie.id}
style={{ height:50 padding:10}}>
<Text> movie.title</Text>
<Text> movie.releaseYear</Text>
</View>
)
}
render() {
return (
<View style={{flex: 1, justifyContent:'center'}}>
{this.state.dataSource.length ? this.renderMovieList(): null}
</View>
);
}

How do you access an object with keys as a React child? - React Native

I am trying to display this JSON data:
[
{
"id":"1",
"imagename":"dog"
},
{
"id":"2",
"imagename":"cat"
},
{
"id":"3",
"imagename":"mouse"
},
{
"id":"4",
"imagename":"deer"
},
{
"id":"5",
"imagename":"shark"
},
{
"id":"6",
"imagename":"ant"
}
]
Here is the current code that I have to display that data:
componentDidMount(){
fetch(`http://www.example.com/React/data.php`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then((response) => response.json())
.then((responseJson) => {
this.data = responseJson;
this.setState({ loading: false });
}).catch((error) => {
console.warn(error);
});
}
return(
<View style = { styles.MainContainer }>
<View>
<Card>
<View>
<Text>{this.data.id}</Text>
<Text>{this.data.imagename}</Text>
</View>
</Card>
</View>
</View>
);
My result is that nothing displays, but when I just have this.data I get the object with keys error again.
Looking up similar answers to find my problem, I then attempted to .map, but I kept getting cannot not find variable: i:
this.data = responseJson.map(item => ({ ...item, i }))
And lastly here is the rest of my code for the attempt:
return(
<View style = { styles.MainContainer }>
<View>
<Card>
<View key={i}>
<Text>{item.id}</Text>
<Text>{item.imagename}</Text>
</View>
</Card>
</View>
</View>
);
When I put my json data into an array, nothing displays because (I'm guessing) there are no commas between the keys. Like this:
{"id":"1","imagename":"dog"}{"id":"2","imagename":"cat"}{"id":"3","imagename":"mouse"}{"id":"4","imagename":"deer"}{"id":"5","imagename":"shark"}{"id":"6","imagename":"ant"}
And if anyone needs to see my data.php:
Echos Object
$dsql = "SELECT * FROM random";
$dresult = $con->query($dsql);
if ($dresult->num_rows >0) {
while($drow[] = $dresult->fetch_assoc()) {
$dtem = $drow;
$djson = json_encode($dtem);
}
} else {
}
echo $djson;
Echos Array
$dsql = "SELECT * FROM random";
$dresult = $con->query($dsql);
if ($dresult->num_rows >0) {
while($drow = $dresult->fetch_assoc()) {
$dtem = $drow;
$djson = json_encode($dtem);
echo $djson;
}
} else {
}
I can see an error on the way you pass the argument i on your map function, please take a look to this simple example of how to use map to render <li> elements.
var dataSample = [
{ "id": "1", "imagename": "dog" },
{ "id": "2", "imagename": "cat" },
{ "id": "3", "imagename": "mouse" },
{ "id": "4", "imagename": "deer" },
{ "id": "5", "imagename": "shark" },
{ "id": "6", "imagename": "ant" }
];
const App = () => (
<div>
<ul>
{dataSample.map((data, i) => {
return <li key={i}>{i + ' - ' + data.imagename}</li>
})}
</ul>
</div>
);
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Resources