Try to render data from Api using Hook in React-Native - react-native

I'm new here and in react-native.
I want render some data from IMDB Api with the "hook" method.
So I try to render data in a flatlist, I can see in the console that the data is retrieved properly in a jSon format witch is a good thing but when I open my app I don't see any rendering on the screen.
I try to use the 'Hook' method and not the 'classes' and I'm pretty sure that I don't use properly the useState method.
So any help or advices are welcome.
My code:
App
import React, { useState } from "react";
import {
View,
Text,
StyleSheet,
Button,
TextInput,
FlatList,
} from "react-native";
// import films from "../Helpers/filmsData";
import FilmsItem from "./FilmsItem";
import getFilmsFromApiWithSearchedText from "../Api/TMDBApi";
const Search = () => {
const [films, setFilms] = useState([]);
const _loadFilms = () => {
getFilmsFromApiWithSearchedText("White").then(
(data) => setFilms({ film: data.results }),
console.log(films)
);
};
return (
<View style={styles.container}>
<TextInput style={styles.input} placeholder="Titre du film" />
<Button
style={styles.button}
title="Rechercher"
onPress={() => _loadFilms()}
/>
<FlatList
data={setFilms.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => <FilmsItem films={item} />}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
},
input: {
marginLeft: 5,
marginRight: 5,
height: 50,
paddingLeft: 5,
borderWidth: 1,
borderColor: "#000000",
},
});
export default Search;
Api request:
// Api/TMDBApi.js
const API_TOKEN = "**************************";
const getFilmsFromApiWithSearchedText = (text) => {
const url =
"https://api.themoviedb.org/3/search/movie?api_key=" +
API_TOKEN +
"&language=en&query=" +
text;
return fetch(url)
.then((response) => response.json())
.catch((error) => console.error(error));
};
export default getFilmsFromApiWithSearchedText;
FilmItem:
import React from "react";
import { View, Text, StyleSheet, Image } from "react-native";
const FilmsItem = (props) => {
const film = props.film;
return (
<View style={styles.container}>
<Image style={styles.img} source={{ uri: "image" }} />
<View style={styles.content}>
<View style={styles.header}>
<Text style={styles.title}>{film.title}</Text>
<Text style={styles.vote}>{film.vote_average}</Text>
</View>
<View style={styles.synopsis}>
<Text style={styles.synopsysText} numberOfLines={6}>
{film.overview}
</Text>
</View>
<View style={styles.date}>
<Text style={styles.dateText}>Sorti le {film.release_date}</Text>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
height: 190,
},
content: {
flex: 1,
margin: 5,
},
img: {
height: 180,
width: 120,
margin: 5,
backgroundColor: "gray",
},
header: {
flex: 3,
flexDirection: "row",
},
title: {
flex: 1,
flexWrap: "wrap",
fontWeight: "bold",
fontSize: 20,
paddingRight: 5,
},
vote: {
fontWeight: "bold",
fontSize: 20,
color: "#666666",
},
synopsis: {
flex: 7,
},
synopsysText: {
fontStyle: "italic",
color: "#666666",
},
date: {
flex: 1,
paddingBottom: 10,
},
dateText: {
textAlign: "right",
fontSize: 14,
},
});
export default FilmsItem;

const _loadFilms = () => {
getFilmsFromApiWithSearchedText("White").then(
(data) => setFilms({ film: data.results }),
console.log(films)
);
};
setFilms({ film: data.results }) will set an object, but you need an array in there.
Try to do something like this: setFilms(data.results)

use useState in this way
const _loadFilms = () => {
getFilmsFromApiWithSearchedText("White").then(
(data) => setFilms(data.results),
console.log(films)
);
};
then in Flatlist you can use like this
return (
<View style={styles.container}>
<TextInput style={styles.input} placeholder="Titre du film" />
<Button
style={styles.button}
title="Rechercher"
onPress={() => _loadFilms()}
/>
<FlatList
data={films}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => <FilmsItem films={item} />}
/>
</View>
);

Related

Looped TextInput have the copy each other

this may sound stupid for the most of you but I'm new when it comes to using API and react native. My situation is the next. From my data I try to display questions and a text field so the customer can answer and therefore I retrieve the data. But my problem is the next on when I display and try to write in the TextInput no matter how I have they will all copy what I write in which ever one I'm writing on. I don't get what I am doing wrong. I tried with looping but I can't seem to get the right answer to solve my problem. Here's my code if someone can help me.
//import liraries
import React, { Component, useEffect, useState } from 'react';
import {
View,
Text,
StyleSheet,
FlatList,
TextInput,
Picker,
} from 'react-native';
// create a component
const Get = ({ navigation }) => {
const [user, setUser] = useState();
// const [text, onChangeText] = React.useState(null);
const [selectedValue, setSelectedValue] = useState("Test");
const [text, onChangeText] = useState('');
const getUserData = async () => {
try {
let response = await fetch('https://survey-back-nmucl6ui6q-ey.a.run.app/survey/7b504f09-7a67-4f99-a402-c15a9388446c', {
headers: new Headers({
'Authorization': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NTUxNTU1MjMsImlhdCI6MTY1NTA2OTExOCwic3ViIjoxfQ.eoLaDT4wP99yjC38DN2Zck2sgwXFvcRYrfzxszHkQvc',
'Content-Type': 'application/x-www-form-urlencoded'
}),
});
let json = await response.json();
console.log(json.question)
setUser(json.question);
} catch (error) {
console.error(error);
}
};
useState(() => {
getUserData();
}, []);
const renderItem = ({ item }) => {
return (
<View
style={{
borderBottomWidth: 1,
borderBottomColor: '#ccc',
padding: 5,
}}>
{item.question_type == 'text-field' ?
<View style={styles.questions}>
<Text style={styles.label}>{item.name}</Text>
<TextInput
style={styles.input}
onChangeText={onChangeText}
value={text}
placeholder="Entrez votre réponse"
/>
</View>
: <Text>Erreur</Text>}
{item.question_type == 'select' ?
<View style={styles.questions}>
<Text style={styles.label}>{item.name}</Text>
<Picker
selectedValue={selectedValue}
onValueChange={(itemValue, itemIndex) =>
setSelectedValue(itemValue)}
>
{Object.keys(item.choice).map(key =>{
return (
<Picker.Item label={key} value={key} key={key} />
)
})}
</Picker>
</View>
: <Text style={{display: 'none'}}>Erreur</Text>}
<View>
{item.question_type == 'comboboxMulti' ?
<Text style={{ fontWeight: 'bold' }}>{item.name}</Text>
: <Text style={{display: 'none'}}>Ça marche pas</Text>}
</View>
</View>
);
};
return (
<View style={styles.container}>
<FlatList
data={user}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
);
};
// define your styles
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10,
borderRadius: 5,
marginLeft: 0,
},
label: {
textTransform: 'capitalize',
},
questions: {
justifyContent: 'center',
alignItems: 'start',
}
});
//make this component available to the app
export default Get;

I am unable to delete items in my React Native app

I am unable to delete items.
This is App.js file main file:
import { useState } from "react";
import {
StyleSheet,
Text,
View,
Button,
TextInput,
FlatList,
} from "react-native";
import Goalresults from "./Componets/Goalresult";
export default function App() {
const [comingdata, SetData] = useState("");
const [listdata, setlistdata] = useState([]);
function fetchText(enteredText) {
SetData(enteredText);
}
function buttonPress() {
setlistdata((newdata) => [
...newdata,
{ text: comingdata, id: Math.random.toString() },
]);
}
I am passing id as parameter here and used filter method so that it filter all the id and delete id from the array list.
function deleteitem(id) {
setlistdata((newdata) => {
return newdata.filter((goal) => goal.id !== id);
});
}
return (
<View style={styles.container}>
<View>
<Text style={styles.goalsc}>Your Goals</Text>
</View>
<View style={styles.container1}>
<TextInput
style={styles.textInput}
placeholder="Add Your Goals here..."
onChangeText={fetchText}
/>
<Button title="Add Goal" onPress={buttonPress} />
</View>
<View style={styles.hello}>
<FlatList
data={listdata}
renderItem={(itemdata) => {
return (
<Goalresults
id={itemdata.item.id}
onDeleteItem={deleteitem}
text={itemdata.item.text}
/>
);
}}
keyExtractor={(item, index) => {
return item.id;
}}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 50,
paddingHorizontal: 16,
},
container1: {
flex: 1,
height: 120,
// paddingTop: 10,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 20,
borderBottomWidth: 1,
borderBottomColor: "#808080",
},
textInput: {
width: "70%",
borderWidth: 1,
borderRadius: 10,
marginRight: 10,
padding: 8,
},
hello: {
flex: 3,
},
goalsc: {
fontSize: 20,
fontWeight: "bold",
paddingLeft: 140,
},
});
Second separated file:
import { View, Text, StyleSheet,Pressable} from "react-native";
function Goalresults(props) {
I used bind there to bind id:
return (
<Pressable onPress={props.onDeleteItem.bind(this,props.id)}>
<View style={styles.goalInput}>
<Text style={styles.textcolor}>{props.text}</Text>
</View>
</Pressable>
);
}
export default Goalresults;
const styles = StyleSheet.create({
goalInput: {
flex: 5,
borderRadius: 5,
paddingTop: 10,
backgroundColor: "#A020F0",
padding: 10,
margin: 10,
},
textcolor: {
color: "white",
},
});
There are a few issues with your code. I will list them as follows.
Inside Goalresults function change the bind on Pressable as
follows: <Pressable onPress={props.onDeleteItem.bind(props, props.id)}>
Inside buttonPress function correct this line { text: comingdata, id: Math.random().toString() }, you missed '()' paranthesis on random
Also on Goalresults add a key={itemdata.item.id}. It will help resolve the warning "duplicate keys".
Following is the complete code
App.js
export default function App() {
const [comingdata, SetData] = useState("");
const [listdata, setlistdata] = useState([]);
function fetchText(enteredText) {
SetData(enteredText);
}
function buttonPress() {
setlistdata((newdata) => [
...newdata,
{ text: comingdata, id: Math.random().toString() },
]);
}
function deleteitem(id) {
console.log('id: ', id)
setlistdata((newdata) => {
return newdata.filter((goal) => goal.id !== id);
});
}
return (
<View style={styles.container}>
<View>
<Text style={styles.goalsc}>Your Goals</Text>
</View>
<View style={styles.container1}>
<TextInput
style={styles.textInput}
placeholder="Add Your Goals here..."
onChangeText={fetchText}
/>
<Button title="Add Goal" onPress={buttonPress} />
</View>
<View style={styles.hello}>
<FlatList
data={listdata}
renderItem={(itemdata) => {
return (
<Goalresults
key={itemdata.item.id}
id={itemdata.item.id}
onDeleteItem={deleteitem}
text={itemdata.item.text}
/>
);
}}
keyExtractor={(item, index) => {
return item.id;
}}
/>
</View>
</View>
);
}
GoalResults.js
function Goalresults(props) {
return (
<Pressable onPress={props.onDeleteItem.bind(props, props.id)}>
<View style={styles.goalInput}>
<Text style={styles.textcolor}>{props.text}</Text>
</View>
</Pressable>
);
}

Showing search icon inside react-native-autocomplete-input component

I am using the react-native-autocomplete-input package for auto-complete searching.
https://www.npmjs.com/package/react-native-autocomplete-input
Here is a template code which works:
//Example of React Native AutoComplete Input
//https://aboutreact.com/example-of-react-native-autocomplete-input/
//import React in our code
import React, {useState, useEffect} from 'react';
//import all the components we are going to use
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
//import Autocomplete component
import Autocomplete from 'react-native-autocomplete-input';
const App = () => {
const [films, setFilms] = useState([]); // For the main data
const [filteredFilms, setFilteredFilms] = useState([]); // Filtered data
const [selectedValue, setSelectedValue] = useState({}); // selected data
useEffect(() => {
fetch('https://aboutreact.herokuapp.com/getpost.php?offset=1')
.then((res) => res.json())
.then((json) => {
const {results: films} = json;
setFilms(films);
//setting the data in the films state
})
.catch((e) => {
alert(e);
});
}, []);
const findFilm = (query) => {
//method called everytime when we change the value of the input
if (query) {
//making a case insensitive regular expression
const regex = new RegExp(`${query.trim()}`, 'i');
//setting the filtered film array according the query
setFilteredFilms(
films.filter((film) => film.title.search(regex) >= 0)
);
} else {
//if the query is null then return blank
setFilteredFilms([]);
}
};
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
containerStyle={styles.autocompleteContainer}
//data to show in suggestion
data={filteredFilms}
//default value if you want to set something in input
defaultValue={
JSON.stringify(selectedValue) === '{}' ?
'' :
selectedValue.title
}
// onchange of the text changing the state of the query
// which will trigger the findFilm method
// to show the suggestions
onChangeText={(text) => findFilm(text)}
placeholder="Enter the film title"
renderItem={({item}) => (
//you can change the view you want to show in suggestions
<TouchableOpacity
onPress={() => {
setSelectedValue(item);
setFilteredFilms([]);
}}>
<Text style={styles.itemText}>
{item.title}
</Text>
</TouchableOpacity>
)}
/>
<View style={styles.descriptionContainer}>
{films.length > 0 ? (
<>
<Text style={styles.infoText}>
Selected Data
</Text>
<Text style={styles.infoText}>
{JSON.stringify(selectedValue)}
</Text>
</>
) : (
<Text style={styles.infoText}>
Enter The Film Title
</Text>
)}
</View>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
flex: 1,
padding: 16,
marginTop: 40,
},
autocompleteContainer: {
backgroundColor: '#ffffff',
borderWidth: 0,
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
},
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
});
export default App;
The input box looks like below.
I want a search icon at the right/left inside of the search input box.
Is there any way I can do this?
Here is the working code with
//Example of React Native AutoComplete Input
//https://aboutreact.com/example-of-react-native-autocomplete-input/
//import React in our code
import React, {useState, useEffect} from 'react';
import AntDesign from 'react-native-vector-icons/AntDesign';
//import all the components we are going to use
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
//import Autocomplete component
import Autocomplete from 'react-native-autocomplete-input';
const App = () => {
const [films, setFilms] = useState([]); // For the main data
const [filteredFilms, setFilteredFilms] = useState([]); // Filtered data
const [selectedValue, setSelectedValue] = useState({}); // selected data
useEffect(() => {
fetch('https://aboutreact.herokuapp.com/getpost.php?offset=1')
.then((res) => res.json())
.then((json) => {
const {results: films} = json;
setFilms(films);
//setting the data in the films state
})
.catch((e) => {
alert(e);
});
}, []);
const findFilm = (query) => {
//method called everytime when we change the value of the input
if (query) {
//making a case insensitive regular expression
const regex = new RegExp(`${query.trim()}`, 'i');
//setting the filtered film array according the query
setFilteredFilms(
films.filter((film) => film.title.search(regex) >= 0)
);
} else {
//if the query is null then return blank
setFilteredFilms([]);
}
};
return (
<View style={{flex: 1}}><View><Text>Hello Friend</Text></View>
<View style={styles.container}>
<View style={styles.searchSection}>
<AntDesign
name="search1"
size={18}
color="gray"
style={styles.searchIcon}
/>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
containerStyle={styles.autocompleteContainer}
inputContainerStyle={styles.inputContainer}
//data to show in suggestion
data={filteredFilms}
//default value if you want to set something in input
defaultValue={
JSON.stringify(selectedValue) === '{}'
? ''
: selectedValue.title + selectedValue.id
}
// onchange of the text changing the state of the query
// which will trigger the findFilm method
// to show the suggestions
onChangeText={(text) => findFilm(text)}
placeholder="Search doctors, specialities, symptoms"
renderItem={({item}) => (
//you can change the view you want to show in suggestions
<View>
<TouchableOpacity
onPress={() => {
setSelectedValue(item);
setFilteredFilms([]);
}}>
<Text style={styles.itemText}>{item.title + item.id}</Text>
</TouchableOpacity>
</View>
)}
/>
<AntDesign
name="close"
size={18}
color="gray"
style={styles.clearIcon}
/>
</View>
<View style={styles.descriptionContainer}>
{films.length > 0 ? (
<>
<Text style={styles.infoText}>
Selected Data
</Text>
<Text style={styles.infoText}>
{JSON.stringify(selectedValue)}
</Text>
</>
) : (
<Text style={styles.infoText}>
Enter The Film Title
</Text>
)}
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
flex: 1,
padding: 16,
marginTop: 40,
},
autocompleteContainer: {
backgroundColor: '#ffffff',
borderWidth: 0,
marginLeft: 10,
marginRight: 10,
//paddingLeft: 15,
},
inputContainer: {
//minWidth: 300,
//width: "90%",
//height: 55,
backgroundColor: 'transparent',
//color: '#6C6363',
//fontSize: 18,
//fontFamily: 'Roboto',
borderBottomWidth: 1,
//borderBottomColor: 'rgba(108, 99, 99, .7)',
borderColor: 'transparent',
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
},
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
// testing below
searchSection: {
flex: 1,
height: 50,
borderRadius: 10,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginLeft: '5%',
marginRight: '5%',
backgroundColor: '#fff',
},
searchIcon: {
//padding: 10,
paddingLeft: 10,
backgroundColor: 'transparent',
},
clearIcon: {
paddingRight: 10,
backgroundColor: 'transparent',
},
});
export default App;
npm install react-native-vector-icons for the AntDesign icons.
I am using "react-native-vector-icons": "^7.1.0".
Your output will be like:
Have a great day!!

how to get current flat list item data in reactnative using react-native-swipe-list-view

I'm not getting how to get the current item object of a flat list
I used react-native-swipeout and react-native-swipe-list-view and in both examples I stuck.
And on google I found very big answers. Which are not pointing only the particular issue which confused me a lot.
the below is the deleted function when I used react-native-swipeout plugin
const swipeSettings = {
left: [
{
text: 'Delete',
onPress: () => {
console.log('-----delete-----');
},
type: 'delete',
},
}
All I need is to get the current item object data like below inside onpress() when i tapped the delete button .
{
id: 1,
prodName : "abcdefg",
}
That's all, I came from native script background and in that framework I never faced such issue. Because the documentation was crystal clear. But here In react native everything seems to be complicated for me.
Kindly any one help me.
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({item, index}) => (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)}
/>
entire page
import React, {useState} from 'react';
import {View} from 'react-native-animatable';
import {
TextInput,
TouchableOpacity,
FlatList,
} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import {StyleSheet, Pressable, Text, Button} from 'react-native';
import * as Animatable from 'react-native-animatable';
import Swipeout from 'react-native-swipeout';
import ButtonPressable from '../../components/ButtonPressable';
var sqlite_wrapper = require('./sqliteWrapper');
const DATA = [
{
prodName: 'Added data will look like this',
},
];
const swipeSettings = {
style: {
marginBottom: 10,
},
autoClose: false,
backgroundColor: 'transparent',
close: false,
disabled: false,
onClose: (sectionID, rowId, direction) => {
console.log('---onclose--');
},
onOpen: (sectionID, rowId, direction) => {
console.log('---onopen--');
},
right: [
{
backgroundColor: 'dodgerblue',
color: 'white',
text: 'Edit',
onPress: () => {
console.log('-----edit-----');
},
},
],
left: [
{
backgroundColor: 'red',
color: 'white',
text: 'Delete',
onPress: () => {
console.log('-----delete-----');
sqlite_wrapper.deleteById
},
type: 'delete',
// component : (<ButtonPressable text="delete" />)
},
],
// buttonWidth: 100,
};
const AddProductList = ({route, navigation}) => {
const {navData} = route.params;
const [prodName, setProdName] = useState('');
var [data, setData] = useState(DATA);
return (
<View style={styles.container}>
<Animatable.View
animation="bounceIn"
duration={1000}
style={styles.inputFieldView}>
<TextInput
style={styles.textInput}
onChangeText={(value) => setProdName(value)}
placeholder="Add the Product"
defaultValue={prodName}
/>
<TouchableOpacity
style={styles.addView}
onPress={() => {
sqlite_wrapper
.insert({prodName: prodName}, sqlite_wrapper.collection_product)
.then((result) => {
console.log('---result---');
console.log(result);
if (result.rowsAffected) {
fetchAllData();
}
});
function fetchAllData() {
sqlite_wrapper
.readAll(sqlite_wrapper.collection_product)
.then((resultData) => {
console.log('---resultData---');
console.log(resultData);
setData(resultData);
setProdName('');
});
}
// without sql this is how to update the state having a array
// const updatedArray = [...data];
// updatedArray.push({prodName: prodName});
// setData(updatedArray);
// setProdName('');
}}>
<Icon name="plus" size={16} style={styles.add} color="white" />
</TouchableOpacity>
</Animatable.View>
<Animatable.View
animation="bounceInLeft"
duration={1500}
style={{flex: 1}}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({item, index}) => (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)}
/>
</Animatable.View>
</View>
);
};
var styles = StyleSheet.create({
container: {
flex: 1,
},
inputFieldView: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
margin: 10,
},
textInput: {
flex: 1,
backgroundColor: '#b2ebf2',
borderTopLeftRadius: 7,
borderBottomLeftRadius: 7,
fontSize: 16,
},
addView: {
backgroundColor: '#0f4c75',
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
borderTopEndRadius: 7,
borderBottomEndRadius: 7,
padding: 9,
},
add: {
padding: 7,
},
listView: {
padding: 20,
backgroundColor: 'green',
margin: 0,
borderRadius: 0,
},
listViewText: {
color: 'white',
},
});
export default AddProductList;
So if I get you right you have one generic swipe setting that you want to adjust to each element in the list.
Try changing the renderItem of the Flatlist like this and let me know how it worked for you:
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item, index }) => {
let right = [...swipeSettings.right]; <---- ADDED
let left = [...swipeSettings.left]; <---- ADDED
right[0].onPress = () => console.log('edit', item.prodName); <---- ADDED
left[0].onPress = () => console.log('delete', item.prodName); <---- ADDED
<Swipeout {...swipeSettings} {...{ right, left}} > <---- CHANGED
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
}}
/>
So what I have done here is sending the generic swipe settings to each instance of Swipeout but changed their "Left" and "Right" in order to overwrite their "onPress" function and adjust it to the rendered item.
I know it is hard to understand it like this and it's probably not the best explanation but I hope it will help you somehow.
EDIT
import React, { useState } from 'react';
import { View } from 'react-native-animatable';
import {
TextInput,
TouchableOpacity,
FlatList,
} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import { StyleSheet, Pressable, Text, Button } from 'react-native';
import * as Animatable from 'react-native-animatable';
import Swipeout from 'react-native-swipeout';
import ButtonPressable from '../../components/ButtonPressable';
var sqlite_wrapper = require('./sqliteWrapper');
const DATA = [
{
prodName: 'Added data will look like this',
},
];
const AddProductList = ({ route, navigation }) => {
const { navData } = route.params;
const [prodName, setProdName] = useState('');
var [data, setData] = useState(DATA);
const renderItem = ({ item, index }) => {
const swipeSettings = {
style: {
marginBottom: 10,
},
autoClose: false,
backgroundColor: 'transparent',
close: false,
disabled: false,
onClose: (sectionID, rowId, direction) => {
console.log('---onclose--');
},
onOpen: (sectionID, rowId, direction) => {
console.log('---onopen--');
},
right: [
{
backgroundColor: 'dodgerblue',
color: 'white',
text: 'Edit',
onPress: () => console.log('-----edit-----', item.prodName)
},
],
left: [
{
backgroundColor: 'red',
color: 'white',
text: 'Delete',
onPress: () => {
console.log('-----delete-----', item.prodName);
sqlite_wrapper.deleteById
},
type: 'delete',
// component : (<ButtonPressable text="delete" />)
},
],
// buttonWidth: 100,
};
return (
<Swipeout {...swipeSettings}>
<View style={styles.listView}>
<Text style={styles.listViewText}>{item.prodName}</Text>
</View>
</Swipeout>
)
}
return (
<View style={styles.container}>
<Animatable.View
animation="bounceIn"
duration={1000}
style={styles.inputFieldView}>
<TextInput
style={styles.textInput}
onChangeText={(value) => setProdName(value)}
placeholder="Add the Product"
defaultValue={prodName}
/>
<TouchableOpacity
style={styles.addView}
onPress={() => {
sqlite_wrapper
.insert({ prodName: prodName }, sqlite_wrapper.collection_product)
.then((result) => {
console.log('---result---');
console.log(result);
if (result.rowsAffected) {
fetchAllData();
}
});
function fetchAllData() {
sqlite_wrapper
.readAll(sqlite_wrapper.collection_product)
.then((resultData) => {
console.log('---resultData---');
console.log(resultData);
setData(resultData);
setProdName('');
});
}
// without sql this is how to update the state having a array
// const updatedArray = [...data];
// updatedArray.push({prodName: prodName});
// setData(updatedArray);
// setProdName('');
}}>
<Icon name="plus" size={16} style={styles.add} color="white" />
</TouchableOpacity>
</Animatable.View>
<Animatable.View
animation="bounceInLeft"
duration={1500}
style={{ flex: 1 }}>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={renderItem}
/>
</Animatable.View>
</View>
);
};
var styles = StyleSheet.create({
container: {
flex: 1,
},
inputFieldView: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
margin: 10,
},
textInput: {
flex: 1,
backgroundColor: '#b2ebf2',
borderTopLeftRadius: 7,
borderBottomLeftRadius: 7,
fontSize: 16,
},
addView: {
backgroundColor: '#0f4c75',
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
borderTopEndRadius: 7,
borderBottomEndRadius: 7,
padding: 9,
},
add: {
padding: 7,
},
listView: {
padding: 20,
backgroundColor: 'green',
margin: 0,
borderRadius: 0,
},
listViewText: {
color: 'white',
},
});
export default AddProductList;

React Native FlatList don't scroll

my FlatList doesn't scroll, I have inserted my FlatList in a SafeAreaView but doesn't work, I can see an item but I can't scroll.
How can I solve this problem?
How can I try?
Thank you
export default function App() {
const [textTodo, setTextTodo] = useState('')
const [arrayTodo, setArrayTodo] = useState([])
const inputTextHandler = (text) => {
setTextTodo(text)
}
const insertTodoHandler = () => {
if (textTodo.trim() === '') {
Alert.alert('ToDo vuoto', 'Devi inserire qualcosa da fare')
return
}
setArrayTodo([...arrayTodo, { value: textTodo, id: Math.random().toString() }])
console.log(arrayTodo)
setTextTodo('')
Keyboard.dismiss()
}
return (
<View>
<Header />
<View style={styles.container}>
<TextInput onChangeText={inputTextHandler} value={textTodo} style={styles.input} placeholder='Cosa hai da fare?' />
<Button title='INSERISCI' onPress={insertTodoHandler} />
</View>
<SafeAreaView>
<FlatList
style={styles.output}
data={arrayTodo}
renderItem={({ item }) => <Text style={styles.outputText}>{item.value}</Text>}
keyExtractor={item => item.id}
/>
</SafeAreaView>
</View>
);
}
I had tried your code it's working fine, might be a problem with your styles check this one I had tried your by changing styles:
import React, { useState} from 'react';
import { View, TextInput, ScrollView, FlatList, SafeAreaView, Button, Text, Keyboard, StyleSheet } from 'react-native';
export default function App() {
const [textTodo, setTextTodo] = useState('')
const [arrayTodo, setArrayTodo] = useState([])
const inputTextHandler = (text) => {
setTextTodo(text)
}
const insertTodoHandler = () => {
if (textTodo.trim() === '') {
Alert.alert('ToDo vuoto', 'Devi inserire qualcosa da fare')
return
}
setArrayTodo([...arrayTodo, { value: textTodo, id: Math.random().toString() }])
console.log(arrayTodo)
setTextTodo('')
}
return (
<View style={{marginTop:50,flex:1}}>
<View style={styles.container}>
<TextInput onChangeText={inputTextHandler} value={textTodo} style={styles.input} placeholder='Cosa hai da fare?' />
<Button title='INSERISCI' onPress={insertTodoHandler} />
</View>
<FlatList
style={styles.output}
data={arrayTodo}
renderItem={({ item }) => <View><Text style={styles.outputText}>{item.value}</Text></View>}
keyExtractor={item => item.id}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding:50,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
},
input: {
borderBottomWidth: 1,
marginVertical: 15,
width: '80%',
marginHorizontal: 5,
paddingLeft: 5
},
output: {
paddingHorizontal: 50,
},
outputText: {
borderWidth: 1,
borderColor: 'grey',
padding: 10,
marginVertical: 5,
borderRadius: 10,
},
shadow: {
shadowOffset: { width: 15, height: 15 },
shadowOpacity: 1
}
});
Hope this helps!