*I use the ref property in the flatlist component in react native, but I get an undefined is not an
object error. I looked at many places on
the internet but did not get a satisfactory answer. Please help me :)*
const DATA = [
{
id: 0,
title: "First Item",
},
{
id: 1,
title: "Second Item",
},
];
const [selectedId, setSelectedId] = useState(null);
**React.useEffect(() => {
this.el.scrollToIndex({ animated: true, index:selectedId});
}, []);**
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.item, style]}>
<Text style={styles.title}>{item.title}</Text>
</TouchableOpacity>
);
const renderItem = ({ item }) => {
const backgroundColor = item.id === selectedId ? "#6e3b6e" : "#f9c2ff";
return (
<Item
item={item}
onPress={() => setSelectedId(item.id)}
style={{ backgroundColor }}
/>
);
};
return (
<>
<FlatList
data={DATA}
horizontal={true}
renderItem={renderItem}
keyExtractor={(item) => item.id}
extraData={selectedId}
**ref={(el) => this.el = el}**strong text
/>
</>
)
}```
To use a ref, you need to use useRef (since you're on a function component). On function components you won't find yourself using this. When using useRef, you'll need to use .current to access the item itself. So, you can see I'm doing el.current.scrollToIndex
Also, you'll need to add selectedId as a dependency to your useEffect
export default function App() {
const DATA = [
{
id: 0,
title: "First Item",
},
{
id: 1,
title: "Second Item",
},
{
id: 2,
title: "Second Item",
},
{
id: 3,
title: "Second Item",
},
{
id: 4,
title: "Second Item",
},
{
id: 5,
title: "Second Item",
},
{
id: 6,
title: "Second Item",
},
];
const [selectedId, setSelectedId] = React.useState(null);
const el = React.useRef()
React.useEffect(() => {
el.current.scrollToIndex({ animated: true, index:selectedId});
}, [selectedId]);
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.item, style]}>
<Text style={styles.title}>{item.title}</Text>
</TouchableOpacity>
);
const renderItem = ({ item }) => {
const backgroundColor = item.id === selectedId ? "#6e3b6e" : "#f9c2ff";
return (
<Item
item={item}
onPress={() => setSelectedId(item.id)}
style={{ backgroundColor }}
/>
);
};
return (
<>
<FlatList
data={DATA}
horizontal={true}
renderItem={renderItem}
keyExtractor={(item) => item.id}
extraData={selectedId}
ref={el}
/>
</>
)
}
Related
I have this nested array
[
{
"id": 1,
"title": "Question 1",
"answers": [
{
"options": 1,
"right_ans": "yes"
},
{
"options": 2,
"right_ans": "no"
}
]
},
{
"id": 2,
"title": "Question 2",
"answers": [
{
"options": 1,
"right_ans": "yes"
},
{
"options": 2,
"right_ans": "no"
}
]
}
]
I have this code in react native
import questions from './questions '
const [data, setdata] = useState([]);
useEffect(() => {
setdata(questions);
}, [])
onChangeValue = (itemSelected, index) => {
// console.log(index);
const newData = data.map(item => {
//console.log(item.answers[index].options)
console.log(item.answers[index].options+':'+itemSelected.options)
//console.log();
if (item.answers[index].options == itemSelected.options) {
return {
...item,
checked : !item.checked
}
}
return {
...item,
checked : item.checked
}
})
//console.log(newData);
setdata(newData)
}
renderItem = ({item, index}) => {
return (
<View>
<Text>Nueov</Text>
<View style={styles.item}>
<Text>{item.title}</Text>
<FlatList
data={item.answers}
renderItem={({ item }) =>
<View>
{item.checked}
<CheckBox
key={item.options}
size={40}
checked={item.checked}
style={styles.ckItem}
onPress={()=> onChangeValue(item, index)}
/>
<View style={styles.WrapText}>
<Text>{item.right_ans}</Text>
</View>
</View>
}
keyExtractor={item => item.options}
/>
</View>
</View>
)
}
onShowItemSelected = () => {
const listSelected = data.filter(item => item.checked == true);
let contentAlert = '';
listSelected.forEach(item=>{
contentAlert = contentAlert + `${item.id}.`+item.apartado+ `\n`;
})
Alert.alert(contentAlert);
}
return (
<SafeAreaView style={styles.container}>
<FlatList
style={styles.list}
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
<View styles={styles.wrapButton}>
<TouchableOpacity style={styles.button} onPress={onShowItemSelected}>
<Text>Mostrar el elemento que seleccionados</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
)
}
When I select any checkbox that runs through me, it measures a 1:1 or 2:1 value, which means the number of the object and the answer I select, I still cannot update the array to be able to incorporate a checked object to know which answer I select
I have a list of category from calling external API and I am displaying it in a flatlist like this in horizontal scroll
but it is not changing state onPress , I want it should change color when user click on particular tab/button
my API json format data is like this
const data = [
{
id: '1',
title: 'General'
},
{
id: '2',
title: 'Student-Visa'
},
{
id: '3',
title: 'Study'
},
{
id: '4',
title: 'Festival'
},
{
id: '5',
title: 'NorthIndian-Food'
},
]
and I am using it as
const renderItem = ({ item, index }) => (
<View key={index} style={selectedCategory === item.title ? styles.activeCategory : styles.categoryContainer}>
<TouchableOpacity
activeOpacity={0.6}
underlayColor={COLORS.white}
onPress={()=>handleCategory(item.title)}
>
<Text>{item.title}</Text>
</TouchableOpacity>
</View>
);
return (
<List
data={data}
renderItem={renderItem}
horizontal={true}
style={styles.container}
contentContainerStyle={styles.contentContainer}
showsHorizontalScrollIndicator={false}
keyExtractor={item => item.id.toString()}
/>
)
const handleSelectedCategory = (title) => {
setSelectedCategory(title);
console.log(selectedCategory);
}
const [selectedCategory, setSelectedCategory] = useState();
I am using it as a separate component in another component
<FAQcategory selectedCategory={selectedCategory} />
any suggestion ? or help what I am doing wrong
Thanks in advance
This might help
const [selectedCategory, setSelectedCategory] = useState(0); // should be item index
const handleCategory = (index) => {
setSelectedCategory(index);
};
const renderItem = ({ item, index }) => (
<View
key={index}
style={
selectedCategory === index
? styles.activeCategory
: styles.categoryContainer
}
>
<TouchableOpacity
....
onPress={() => handleCategory(index)} // send index in param
>
....
</TouchableOpacity>
</View>
);
I created a checkbox inside my flatlist but when I click on the checkbox all the check boxes will render. I want to render the checkbox I press not the entire checkboxes.
This is my code.
const ScreenCart = () => {
const [checked, setChecked] = useState(false)
const renderItem = ({ item, index }) => {
return (
<View style={styles.list}>
<View style={{ flexDirection: 'row' }}>
<CheckBox
checkBoxColor={COLORS.ORANGE}
isChecked={checked}
onClick={() => setChecked(!checked)}
/>
<Image
source={item.image}/>
<View>
<Text numberOfLines={1} style={[styles.item, { width: 210 * rate }]}>{item.name}
</Text>
</View>
</View>
</View>
)
}
return (
<View style={{ backgroundColor: COLORS.WHITE, flex: 1 }}>
<View style={{ flex: 1 }}>
<Flatlist
data={TEMP_DATA_CART}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}>
/>
</View>
)
this is my data.
TEMP_DATA_CART = [
{
id: '1', image: IMAGES.imgPromote, name: 'Sữa tắm Prunus - Premier Herb', value: 180000, quantity: 1, checked: false,
},
{
id: '2', image: IMAGES.imgPromote, name: 'Sữa tắm Prunus - Premier Herb', value: 180000, quantity: 1, checked: false,
},
{
id: '3', image: IMAGES.imgPromote, name: 'Sữa tắm Prunus - Premier Herb', value: 180000, quantity: 1, checked: false,
},
you set a global state so it is selecting checkbox for all items
remove this
const [checked, setChecked] = useState(false)
set array of selected id's
const [checked, setChecked] = useState([]);
on press set id in array and set check status from array
<CheckBox
checkBoxColor={COLORS.ORANGE}
isChecked={checked.includes(item.id)}
onClick={() => {
const newIds = [...checked];
const index = newIds.indexOf(item.id);
if (index > -1) {
newIds.splice(index, 1);
} else {
newIds.push(item.id)
}
setChecked(newIds)
}}
/>
and in flatlist set extraData prop
<Flatlist
data={TEMP_DATA_CART}
renderItem={renderItem}
extraData={checked}
keyExtractor={(item) => item.id.toString()}>
/>
to retrive selected id's you can get from checked array
here is the app, I want to create diferent screens with diferent catergories in this case I have Dermatologista and Hospital, how can I select just one description
const [state, setState] = useState({
places: [
{
id: 1,
title: 'Clinica da pele',
description: 'Dermatologista',
latitude:-2.42206406,
longitude:-54.71947789,
},
{
id: 2 ,
title:'Unimed',
description:'Hospital',
latitude:-2.42501721,
longitude:-54.71146077,
},
{
id: 3,
title: 'Dra. Josimar',
description:'Dermatologista',
latitude: -2.4288346,
longitude:-54.7290553,
}
]
});
return(
I just want to select the items with the description == dermatologista
how can I do this ?
<SafeAreaView>
<FlatList
styles = {styles.PlaceContainer}
showsVerticalScrollIndicator
data={state.places}
keyExtractor={item => item.id}
renderItem={({ item }) => {
return(
<View key={item.id} style={styles.place} >
<Text>{item.title}</Text>
<Text>{item.description}</Text>
</View>
)
}
}
/>
</SafeAreaView>
)
}
You can use array.filter :
const filteredPlaces = state.places.filter( place => place.description === "Dermatologista" )
and pass filteredPlaces instead of the entire object to the child component.
Try this
<SafeAreaView>
<FlatList
styles = {styles.PlaceContainer}
showsVerticalScrollIndicator
data={state.places}
keyExtractor={item => item.id}
renderItem={({ item }) => {
item.description == "dermatologista" ? (
<View key={item.id} style={styles.place} >
<Text>{item.title}</Text>
<Text>{item.description}</Text>
</View>
):""
}
}
/>
</SafeAreaView>
I created a flatlist and a float icon to delete a item from flat list but before it's get delete user will get Alert and on press yes it will b deleted everything is working but after pressing yes item didn't deleted. How can i delete it?
Here is my code
state = {
modal: false,
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
{
key: "2",
title: "John Cena",
des: "As you can see, You can't see me!",
image: require("../assets/cena.jpg"),
},
],
image: null,
};
deleteItem = (key) => {
Alert.alert("Delete", "Are You Sure?", [
{
text: "Yes",
onPress: this.setState({
post: this.state.post.filter((item) => item.key !== key),
}),
},
{ text: "no" },
]);
};
render(){return(
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.7}
onPress={this.deleteItem}
style={styles.Delete}
>
<MaterialCommunityIcons name="delete" color="red" size={30} />
</TouchableOpacity>
Someone please help,.............................
You might need to pass the item or an index of the item to the function, but I'm not sure of the internals of the TouchableOpacity component. The following shows how to pass the item and its key to the deleteItem method:
deleteItem = (item) => {
Alert.alert("Delete", "Are You Sure?", [
{
text: "Yes",
onPress: () => this.setState({ // edited
post: this.state.post.filter((p) => p.key !== item.key),
}),
},
{ text: "no" },
]);
};
render(){
return(
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => this.deleteItem(item)}
style={styles.Delete}
>
<MaterialCommunityIcons name="delete" color="red" size={30} />
</TouchableOpacity>
</>
)}
/>
);
};
In the FlatList
You have to use the prop keyExtractor inside the FlatList. (By doing this you assign a key to every object inside the array)
You also have to pass in the key inside your “deleteItem()” function
Like I have done in the below codes
import React from 'react'
import {View, Text,StyleSheet, FlatList,TouchableOpacity,Alert} from 'react-native'
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false,
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
},
{
key: "2",
title: "John Cena",
des: "As you can see, You can't see me!",
},
],
image: null,
};
}
deleteItem = (key) => {
Alert.alert("Delete", "Are You Sure?", [
{
text: "Yes",
onPress:()=> this.setState({
post: this.state.post.filter((item) => item.key !== key),
}),
},
{ text: "no",
onPress:()=>null },
]);
};
render(){return(
<View style={{flex:1}}>
<FlatList
data={this.state.post}
keyExtractor={(item)=> item.key}
renderItem={({ item }) => (
<TouchableOpacity
onPress={()=>{this.deleteItem(item.key)}}
>
<View>
<Text>`Click here to Delete this =${item.title}`</Text>
<MaterialCommunityIcons name="delete" color="red" size={30} />
</View>
</TouchableOpacity>
)}/>
</View>
)}
}