im writing a todolist with reactnative using hooks , however when rendering todo items , its not showing up, any advice to fix this
thank you so much for your help!!!
import React, { useState } from 'react';
import { StyleSheet, FlatList, Text, View } from 'react-native';
export default function App() {
const [todos, setTodos] = useState([
{ text: 'budddy', key: '1' },
{ text: 'helloddd', key: '2' },
{ text: "hellddo", key: '3' }
])
return (
<View style={styles.container} >
<View style={styles.content}>
<FlatList data={todos} renderItem={({ item }) => {
<Text> {item.text}</Text>
}} />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
paddingTop: 30,
},
content: {
padding: 40
},
})
Check the renderItem code you need to add return or use the implicit return of arrow function
<FlatList data={todos} renderItem={({ item }) => (
<Text> {item.text}</Text>
)} />
Use the extraData property on your FlatList component.
As per documentation:
Bypassing extraData={this.state} to FlatList we make sure FlatList will re-render itself when the state.selected changes. Without setting this prop, FlatList would not know it needs to re-render any items because it is also a PureComponent and the prop comparison will not show any changes.
here is the example code (documentation)
import React from 'react';
import {
SafeAreaView,
TouchableOpacity,
FlatList,
StyleSheet,
Text,
} from 'react-native';
import Constants from 'expo-constants';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
function Item({ id, title, selected, onSelect }) {
return (
<TouchableOpacity
onPress={() => onSelect(id)}
style={[
styles.item,
{ backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' },
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
export default function App() {
const [selected, setSelected] = React.useState(new Map());
const onSelect = React.useCallback(
id => {
const newSelected = new Map(selected);
newSelected.set(id, !selected.get(id));
setSelected(newSelected);
},
[selected],
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.title}
selected={!!selected.get(item.id)}
onSelect={onSelect}
/>
)}
keyExtractor={item => item.id}
extraData={selected}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: Constants.statusBarHeight,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
Related
I am new to ReactNative programming and .tsx files in general. I'm trying to display a basic FlatList and have copied the below code from the ReactNative docs here: (https://reactnative.dev/docs/flatlist). It's only slightly modified to fit into my ReactNative app which I am editing in Visual Studio code.
Does anyone know the correct way to display a FlatList? I've spent 2-3 days tinkering with this but I'm obviously missing some crucial ingredient. Beats me.
import * as React from "react";
import { useState, Component } from "react";
import EditScreenInfo from "../components/EditScreenInfo";
import { StyleSheet, Text, View, Dimensions, TouchableOpacity, Alert, FlatList, SafeAreaView, StatusBar } from "react-native";
// import PaymentScreen from "./PaymentScreen";
import { Driver } from "../models/Driver";
// tslint:disable-next-line:typedef
const styles = StyleSheet.create({
page: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#FFF"
},
container: {
height: 750,
width: 750,
backgroundColor: "tomato"
},
map: {
flex: 1,
height:750,
width:750
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
title: {
fontSize: 18
}
});
// tslint:disable-next-line: typedef
const DATA = [
{
id: "bd7acbea-c1b1-46c2-aed5-3ad53abb28ba",
title: "First Item",
},
{
id: "3ac68afc-c605-48d3-a4f8-fbd91aa97f63",
title: "Second Item",
},
{
id: "58694a0f-3da1-471f-bd96-145571e29d72",
title: "Third Item",
},
];
// tslint:disable-next-line:typedef
const Item = ({ item, onPress, backgroundColor, textColor }: {
item: any;
onPress: any;
backgroundColor: any;
textColor: any;
}) => (
<TouchableOpacity onPress={onPress} style={[styles.item, backgroundColor]}>
<Text style={[styles.title, textColor]}>{item.title}</Text>
</TouchableOpacity>
);
export default class TabFourScreen extends Component {
drivers: Driver[] = []; // fetch these from backend... for now you can STUB
selectedId: any = useState(null);
setSelectedId: any = useState(null);
renderItem: any = ({ item }: {item: any}) => {
// tslint:disable-next-line:typedef
const backgroundColor = item.id === this.selectedId ? "#6e3b6e" : "#f9c2ff";
// tslint:disable-next-line:typedef
const color = item.id === this.selectedId ? "white" : "black";
return (
<Item
item={item}
onPress={() => this.setSelectedId(item.id)}
backgroundColor={{ backgroundColor }}
textColor={{ color }}
/>
);
}
render = () => {
return (
<View style={styles.page}>
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={this.renderItem}
keyExtractor={(item) => item.id}
extraData={this.selectedId}
/>
</SafeAreaView>
</View>
);
}
}
First of all you can't use hooks like useState in a Class Component, you have to use Function Component: https://reactnative.dev/docs/getting-started#function-components-and-class-components.
Secondly, you have set width: 750 to your SafeAreaView's style, so the text doesn't appear on the screen you see but appears before.
Try this code:
import * as React from 'react';
import { useState, Component } from 'react';
import {
StyleSheet, Text, View, Dimensions, TouchableOpacity, Alert, FlatList, SafeAreaView, StatusBar,
} from 'react-native';
// import PaymentScreen from "./PaymentScreen";
// tslint:disable-next-line:typedef
const styles = StyleSheet.create({
page: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFF',
},
container: {
height: 750,
width: '100%',
backgroundColor: 'tomato',
},
map: {
flex: 1,
height: 750,
width: 750,
},
item: {
height: 44,
},
title: {
fontSize: 25,
color: 'white',
},
});
// tslint:disable-next-line: typedef
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
// tslint:disable-next-line:typedef
const Item = ({
item, onPress, backgroundColor, textColor,
}) => (
<TouchableOpacity onPress={onPress} style={[styles.item, backgroundColor]}>
<Text style={[styles.title, textColor]}>{item.title}</Text>
</TouchableOpacity>
);
const TabFourScreen = () => {
const [selectedId, setSelectedId] = useState(null);
const renderItem = ({ item }) => {
// tslint:disable-next-line:typedef
const backgroundColor = item.id === selectedId ? '#6e3b6e' : '#f9c2ff';
// tslint:disable-next-line:typedef
const color = item.id === selectedId ? 'white' : 'black';
return (
<Item
item={item}
key={item.id}
onPress={() => setSelectedId(item.id)}
backgroundColor={{ backgroundColor }}
textColor={{ color }}
/>
);
};
return (
<View style={styles.page}>
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={(item) => item.id}
extraData={selectedId}
/>
</SafeAreaView>
</View>
);
};
export default TabFourScreen;
I removed typescript just to test, feel free to add it again.
don't use this.renderItem use only renderItem
i have two screens one for documents (parent) and one for each document(child),when a document on my flatlist of docs is pressed it navigates to the document screen, on that screen i can perform CRUD operations one of them is giving a label to the document, this part is necessary because in order to send the document it must be labeled, however when i label the document the database receives the PUT requests and updates the element but the child screen is not getting the new updated object and i can only send if i navigate back to documents then to document.
How can i solve this?
this is my document label function:
const LabelItem=()=>{
const modefiedFile=new FormData();
modefiedFile.append('file', {
uri: fileUri,
name: fileTitle,
type: 'file/pdf'})
modefiedFile.append('label',Label)
const headers={
Accept:'application/json',
'Content-Type': 'multipart/form-data'
}
console.log(modefiedFile)
axios
.put(`http://192.168.1.17:8000/File/${key}/`,modefiedFile,{headers:headers})
.then((response)=> {response})
.then((error)=>{console.log(error)})
setSecondModal(false)
}
this is the button to send:
<View style={footerStyle.footer}>
<TouchableOpacity onPress={()=> {
label!='none'?
props.navigation.navigate('Envoi'): openAlert()
console.log(label)
}}>
<Icon style={footerStyle.ellipsis} name="share" />
</TouchableOpacity>
and this is from the parent navigation :
<TouchableOpacity onPress={()=>props.navigation.navigate('Document',{url:{uri: `${item.file}`, file:`${item.title}`,key:`${item.id}`,label:`${item.label}`}})}>
<View style={DocumentStyle.flatitem}>
<Icon style={DocumentStyle.pdf} name="file-pdf-o" color="#666"/>
<Text style={DocumentStyle.itemtext}> {item.title}</Text>
</View>
</TouchableOpacity>
for this, you have to change an item on the child screen and pass that item to the parent screen. Please See This.
This is the List Screen.
import React from 'react';
import { useState } from 'react';
import { SafeAreaView, FlatList, StyleSheet,DeviceEventEmitter, Text, StatusBar, TouchableOpacity } from 'react-native';
const App = ({navigation}) => {
DeviceEventEmitter.addListener("imagechange", (eventData) => {
onSelect(eventData)
})
const [data , setData] = useState([
{id: '1',title: 'First Item'},
{id: '2',title: 'Second Item'},
{id: '3',title: 'Third Item'},
{id: '4',title: 'Fourth Item'},
{id: '5',title: 'Fifth Item'},
{id: '6',title: 'Sixth Item'},
{id: '7',title: 'seventh Item'},
{id: '8',title: 'eight Item'},
{id: '9',title: 'nineth Item'},
])
const onSelect = item => {
// let id = data.findIndex((obj => obj.id == item.id));
// const newstate = {...data,data[id].title = item.title}
const newState = data.map(obj =>
obj.id === item.id ? { ...obj, title: item.title } : obj
);
setData(newState)
};
const onPress = (item) => {
navigation.navigate("Details", {item});
};
const renderItem = ({ item }) => (
<TouchableOpacity style={styles.item}
onPress={() => onPress(item)}>
<Text style={styles.title}>{item.title}</Text>
</TouchableOpacity>
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight || 0,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
export default App;
Here are the details Screen Where I am changing the object.
import * as React from 'react';
import { useState, useEffect } from 'react';
import { View, Text, StyleSheet,DeviceEventEmitter, TouchableOpacity } from 'react-native';
function DetailsScreen ({navigation, route}) {
const [item, setItem] = useState(route.params.item)
let data = route.params.item;
const updatevalue = () => {
setItem({...item,title:"updated"})
navigation.goBack();
DeviceEventEmitter.emit("imagechange",{...data,title:"updated this value"});
// route.params.onSelect({...data,title:"updated this value"});
}
// useEffect(() => {
// return () => {
// DeviceEventEmitter.removeAllListeners()
// };
// }, []);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{item.title}</Text>
<TouchableOpacity style={styles.button} onPress={() => updatevalue()}>
<Text style={{color:"#fff"}}>Update Value</Text>
</TouchableOpacity>
</View>
);
}
export default DetailsScreen
const styles = StyleSheet.create({
button:{
marginTop:20,
backgroundColor:"#333333",
borderRadius:10,
paddingHorizontal:20,
paddingVertical:5,
}
})
Here is the link to git repos
Do you have any ideas?
P.S. I need a ListHeaderComponent
orig pic
You should add style in container and override other style like this
import React from 'react';
import {
SafeAreaView,
TouchableOpacity,
FlatList,
StyleSheet,
Text,
View
} from 'react-native';
import Constants from 'expo-constants';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
function Item({ id, title, selected, onSelect }) {
return (
<TouchableOpacity
onPress={() => onSelect(id)}
style={[
styles.item,
{ backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' },
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
export default function App() {
const [selected, setSelected] = React.useState(new Map());
const onSelect = React.useCallback(
id => {
const newSelected = new Map(selected);
newSelected.set(id, !selected.get(id));
setSelected(newSelected);
},
[selected],
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
ListHeaderComponent={()=><View style={{height:80,backgroundColor:'red'}}/>}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.title}
selected={!!selected.get(item.id)}
onSelect={onSelect}
/>
)}
keyExtractor={item => item.id}
extraData={selected}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: Constants.statusBarHeight,
backgroundColor:'green'
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
As I indicated in the Picture with arrow mark, I would like to get the top positions of FlatList. I tried onLayout props, But it return only null values.
Is there anyway to get the top positions of FlatList?
Check below sample
import React, {Component} from 'react';
import {View, FlatList, StyleSheet, Text} from 'react-native';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
export default class HomeScreen extends Component {
findDimesions = layout => {
const {x, y, width, height} = layout;
console.log(x);
console.log(y);
console.log(width);
console.log(height);
};
render() {
return (
<View
onLayout={event => this.findDimesions(event.nativeEvent.layout)}
style={styles.container}>
<FlatList
data={DATA}
renderItem={({item}) => (
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
Change this according to your requirements.
Hope this helps you. Feel free for doubts.
return (
<View style={styles.container}>
<SafeAreaView style={styles.top} />
<FlatList
...
/>
</View>
);
}
const styles = StyleSheet.create({
top: { flex: 0 },
}
How to set a value on text component when i clicked on an item of the flatlist in react-native?
I want to display the value of the flatlist on the text component. When I clicked on an item of a flatlist. So please help me how i can achieve this functionality.
This is the working example as below , please also find the code and if you have any doubts please check :
expo-snack
import React from 'react';
import {
SafeAreaView,
TouchableOpacity,
FlatList,
StyleSheet,
Text,
TextInput
} from 'react-native';
import Constants from 'expo-constants';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
function Item({ id, title, selected, onSelect }) {
return (
<TouchableOpacity
onPress={() => {onSelect(id)}}
style={[
styles.item,
{ backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' },
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
export default function App() {
const [selected, setSelected] = React.useState(new Map());
const [textValue, setValueText] = React.useState(0);
const onSelect = React.useCallback(
id => {
const newSelected = new Map(selected);
newSelected.set(id, !selected.get(id));
setSelected(newSelected);
setValueText(id)
},
[selected],
);
return (
<SafeAreaView style={styles.container}>
<TextInput style={{height:80,width:300}} value={textValue}/>
<FlatList
data={DATA}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.title}
selected={!!selected.get(item.id)}
onSelect={onSelect}
/>
)}
keyExtractor={item => item.id}
extraData={selected}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: Constants.statusBarHeight,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
Hope it helps. feel free for doubts
kindly pass argument onselect function using below code and check out
import React from 'react';
import {
SafeAreaView,
TouchableOpacity,
FlatList,
StyleSheet,
Text,
TextInput
} from 'react-native';
import Constants from 'expo-constants';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
function Item({ id, title, selected, onSelect }) {
return (
<TouchableOpacity
onPress={() => {onSelect(id)}}
style={[
styles.item,
{ backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' },
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
export default function App() {
const [selected, setSelected] = React.useState(new Map());
const [textValue, setValueText] = React.useState("");
const onSelect = React.useCallback(
id => {
const newSelected = new Map(selected);
newSelected.set(id, !selected.get(id));
setSelected(newSelected);
setValueText(id)
},
[selected],
);
const showTitle = (title) =>{
setValueText(title)
}
return (
<SafeAreaView style={styles.container}>
<TextInput style={{height:80,width:300}} value={textValue}/>
<FlatList
data={DATA}
renderItem={({ item }) => (
<Item
id={item.id}
title={item.title}
selected={!!selected.get(item.id)}
onSelect={()=>showTitle(item.title)}
/>
)}
keyExtractor={item => item.id}
extraData={selected}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: Constants.statusBarHeight,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});