i got this This error
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of RestApi.
This is my code App.js
import React from 'react';
import { StyleSheet } from 'react-native';
import RestApi from './x/RestApi';
export default function App() {
return (
<RestApi/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
color: 'white',
alignItems: 'center',
justifyContent: 'center',
}
})
This is my code RestApi.js
import axios from 'axios';
import React, { useState, useEffect } from 'react'
import { Button, Flatlist, SafeAreaView, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
export default function RestApi() {
const [title, setTitle] = useState("");
const [value,setValue] = useState("");
const [items, setItems] = useState([]);
const [button, setButton] = useState("Simpan");
const [selectedUser, setSelectedUser] = useState({});
const submit =()=>{
const data = {
value,title
}
//console.log(data)
if(button=="Simpan"){
axios.post('https://achmadhilmy-sanbercode.my.id/api/v1/news', data)
.then(res=>{
console.log('res: ', res)
setTitle("")
setValue("")
GetData()
}).catch(err=>{
console.log('error: ',err)
})
}else{
axios.put(`https://achmadhilmy-sanbercode.my.id/api/v1/news/${selectedUser.id}`, data)
.then(res=>{
console.log('res: ',res)
setTitle("")
setValue("")
GetData()
setButton("Simpan")
}).catch(err=>{
console.log('error: ', err)
})
}
}
const onSelectItem = (item)=>{
console.log(item)
setSelectedUser(item)
setTitle(item.title)
setValue(item.value)
setButton("Update")
}
const GetData=()=>{
axios.get('https://achmadhilmy-sanbercode.my.id/api/v1/news')
.then(res=>{
const data1 = (res.data.data)
console.log('res: ', data1)
setItems(data1)
})
}
const onDelete=(item)=>{
axios.delete(`https://achmadhilmy-sanbercode.my.id/api/v1/news/${item.id}`)
.then(res=>{
console.log('res: ', res)
GetData()
}).catch(err=>{
console.log('error: ', err)
})
}
useEffect(() => {
GetData()
}, [])
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>Tampilkan Api (CRUD)</Text>
</View>
<View style={styles.content1}>
<Text>Post Data</Text>
<TextInput
placeholder="Masukan judul berita"
style={styles.input}
value={title}
onChangeText={(value)=>setTitle(value)}
/>
<TextInput
placeholder="Masukan Isi berita"
style={styles.input}
value={value}
onChangeText={(value)=>setValue(value)}
/>
<Button
title={button}
onPress={submit}
/>
</View>
<View style={styles.content1}>
<Text>Get Data Berita</Text>
<Flatlist
data={items}
keyExtractor={(item, index) => `${item.id}-${index}`}
renderItem={({item})=>{
return (
<View>
<TouchableOpacity onPress={()=>onDelete(item)}>
<Text style={{color: 'red', alignSelf: 'flex-end'}}>X</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>onSelectItem(item)}style={{borderRadius: 6,backgroundColor:'grey', padding: 5, marginBottom:10}}>
<Text style={{color: 'white'}}>{item.title}</Text>
<Text style={{color: 'white'}}>{item.value}</Text>
</TouchableOpacity>
</View>
)
}}
/>
</View>
</View>
)
}
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:'white'
},
header:{
paddingTop: 50,
paddingHorizontal: 16,
backgroundColor: 'grey',
alignItems: 'center'
},
title:{
color: 'white',
fontSize: 20
},
content1:{
paddingHorizontal: 16
},
input:{
borderWidth:1,
paddingVertical: 10,
paddingHorizontal: 5,
borderRadius: 6,
marginTop: 10
},
contentNews:{
backgroundColor:'grey',
paddingVertical:10
}
})
Your RestApi component does return anything, because the return statement is nested within the submit function, but that does not get called.
Could you try unnesting the return statement? See example below, where I also unnested the useEffect call and several other functions.
import axios from 'axios'
import React, { useState, useEffect } from 'react'
import {
Button,
Flatlist,
SafeAreaView,
ScrollView,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View
} from 'react-native'
export default function RestApi() {
const [title, setTitle] = useState('')
const [value, setValue] = useState('')
const [items, setItems] = useState([])
const [button, setButton] = useState('Simpan')
const [selectedUser, setSelectedUser] = useState({})
const submit = () => {
const data = {
value,
title
}
//console.log(data)
if (button == 'Simpan') {
axios
.post('https://achmadhilmy-sanbercode.my.id/api/v1/news', data)
.then(res => {
console.log('res: ', res)
setTitle('')
setValue('')
GetData()
})
.catch(err => {
console.log('error: ', err)
})
} else {
axios
.put(
`https://achmadhilmy-sanbercode.my.id/api/v1/news/${selectedUser.id}`,
data
)
.then(res => {
console.log('res: ', res)
setTitle('')
setValue('')
GetData()
setButton('Simpan')
})
.catch(err => {
console.log('error: ', err)
})
}
}
const onSelectItem = item => {
console.log(item)
setSelectedUser(item)
setTitle(item.title)
setValue(item.value)
setButton('Update')
}
const GetData = () => {
axios
.get('https://achmadhilmy-sanbercode.my.id/api/v1/news')
.then(res => {
const data1 = res.data.data
console.log('res: ', data1)
setItems(data1)
})
}
const onDelete = item => {
axios
.delete(
`https://achmadhilmy-sanbercode.my.id/api/v1/news/${item.id}`
)
.then(res => {
console.log('res: ', res)
GetData()
})
.catch(err => {
console.log('error: ', err)
})
}
useEffect(() => {
GetData()
}, [])
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>Tampilkan Api (CRUD)</Text>
</View>
<View style={styles.content1}>
<Text>Post Data</Text>
<TextInput
placeholder="Masukan judul berita"
style={styles.input}
value={title}
onChangeText={value => setTitle(value)}
/>
<TextInput
placeholder="Masukan Isi berita"
style={styles.input}
value={value}
onChangeText={value => setValue(value)}
/>
<Button title={button} onPress={submit} />
</View>
<View style={styles.content1}>
<Text>Get Data Berita</Text>
<Flatlist
data={items}
keyExtractor={(item, index) => `${item.id}-${index}`}
renderItem={({ item }) => {
return (
<View>
<TouchableOpacity
onPress={() => onDelete(item)}>
<Text
style={{
color: 'red',
alignSelf: 'flex-end'
}}>
X
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => onSelectItem(item)}
style={{
borderRadius: 6,
backgroundColor: 'grey',
padding: 5,
marginBottom: 10
}}>
<Text style={{ color: 'white' }}>
{item.title}
</Text>
<Text style={{ color: 'white' }}>
{item.value}
</Text>
</TouchableOpacity>
</View>
)
}}
/>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white'
},
header: {
paddingTop: 50,
paddingHorizontal: 16,
backgroundColor: 'grey',
alignItems: 'center'
},
title: {
color: 'white',
fontSize: 20
},
content1: {
paddingHorizontal: 16
},
input: {
borderWidth: 1,
paddingVertical: 10,
paddingHorizontal: 5,
borderRadius: 6,
marginTop: 10
},
contentNews: {
backgroundColor: 'grey',
paddingVertical: 10
}
})
Related
I am trying to display some fetched products in a FlatList, also to display more products when I reach the end of this FlatList, but I am getting this error: Invariant Violation: ScrollView child layout (["alignItems"]) must be applied through the contentContainerStyle prop.
When I change alignItems from style to contentContainerStyle the app closes without showing an error or alert.
If I remove the alignItems from container the app closes too
export default function NewProducts() {
const [products, setProducts] = useState([]);
const [isLoading, setisLoading] = useState(false);
const [startLimit, setStartLimit] = useState({ start: 0, limit: 10 });
const navigation = useNavigation();
useEffect(() => {
setisLoading(true);
getProducts();
}, [startLimit]);
const gotoProduct = (id) => {
navigation.push("product", { idProduct: id });
};
const getProducts = async () => {
const response = await getLastProductsApi(
startLimit.start,
startLimit.limit
);
console.log(response);
setProducts(response);
};
const renderItem = ({product}) => {
return (
<TouchableWithoutFeedback
key={product.id}
onPress={() => gotoProduct(product.id)}
>
<View style={styles.containerProduct}>
<View style={styles.product}>
<Image
style={styles.image}
source={{
uri: `${product.attributes.images.data[0].attributes.formats.small.url}`,
}}
/>
<Text style={styles.name} numberOfLines={1} ellipsizeMode="tail">
{product.attributes.title}
</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
};
const renderFooter = () => {
return isLoading && <Loading text="Loading more products" size="medium" />;
};
const handleLoadMore = () => {
setStartLimit({
start: startLimit.start + 10,
limit: startLimit.limit + 10,
});
setisLoading(true);
};
return (
<FlatList
style={styles.container}
numColumns={2}
data={products}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
ListFooterComponent={renderFooter}
onEndReached={handleLoadMore}
onEndReachedThreshold={0}
/>
);
}
const styles = StyleSheet.create({
container: {
alignItems: "flex-start",
marginTop: 1,
},
containerProduct: {
padding: 3,
},
product: {
padding: 10,
backgroundColor: "#f0f0f0",
borderRadius: 20,
},
image: {
height: 150,
resizeMode: "contain",
borderRadius: 20,
},
name: {
marginTop: 15,
fontSize: 15,
},
});
Here is where I call this component
export default function Home() {
return (
<>
<StatusBarCustom
backgroundColor={colors.primary}
barStyle="light-content"
/>
<Search />
<View>
<Banner />
<NewProducts />
</View>
</>
);
}
When you use renderItem from FlatList you have to use item and not product: https://reactnative.dev/docs/flatlist#required-renderitem
You can replace
const renderItem = ({product}) => {
By
const renderItem = ({item}) => {
I am relatively new to react natuve and I am reading data from my firestore db and I can see the title and id in my console after:
console.log(doc.id, doc.data());
but the items dont show in my flatlist and it just displays a constant loading symbol
this is my code and i cannot figure out why it wont load into my flatlist. Any help is appreciated
`
import { Pressable, Text, TextInput, View, StyleSheet,
SafeAreaView, FlatList, ActivityIndicator } from 'react-native'
import React, { useState, useEffect } from 'react'
import Exercise from '../../components/Exercise'
import { MaterialIcons } from '#expo/vector-icons';
import { auth, app, db, getFirestore, collection, addDoc, getDocs } from '../../firebase'
const WorkoutScreen = () => {
const [exerciseTitle, setTitle] = useState('');
const [exerciseList, setExerciseList] = useState([]);
const addExercise = async() => {
try {
const docRef = await addDoc(collection(db, "Exercise"), {
title: exerciseTitle,
isChecked: false,
});
console.log("Document written with ID: ", docRef.id);
setTitle("");
} catch (e) {
console.error("Error adding document: ", e);
}
};
const getExercise = async() => {
const querySnapshot = await getDocs(collection(db, "Exercise"));
querySnapshot.forEach((doc) => {
console.log(doc.id, doc.data());
setExerciseList({
...doc.data(),
id: doc.id,
title: doc.exerciseTitle,
});
});
};
useEffect ( () => {
getExercise();
}, []);
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
{/* heading */}
<Text style={styles.heading}>Workout List</Text>
{/* shopping items */}
<Text style={styles.noOfExercises}>0</Text>
{/* delete all */}
<Pressable>
<MaterialIcons name="delete" size={32} color="black" />
</Pressable>
</View>
{exerciseList.length > 0 ? (
<FlatList
data={exerciseList}
renderItem ={({item}) => <ExerciseItem title={item.exerciseTitle}/>}
keyExtractor={(item) => item.id}
/>
) : (
<ActivityIndicator />
)}
<TextInput
placeholder='Enter Excercise'
style={styles.input}
value={exerciseTitle}
onChangeText={(text) => setTitle(text)}
onSubmitEditing={addExercise}
/>
</SafeAreaView>
)
}
export default WorkoutScreen
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
flexDirection: 'row',
width: '90%',
alignSelf: 'center',
padding: 10,
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 10,
},
heading: {
fontWeight: '900',
fontStyle: 'bold',
fontSize: 30,
flex: 1,
marginTop: 20,
},
noOfExercises: {
fontSize: 20,
fontWeight: '500',
marginRight: 20,
},
input: {
backgroundColor: 'lightgrey',
padding: 10,
fontSize: 17,
width: '90%',
alignSelf: 'center',
marginTop: 'auto',
borderRadius: 10,
}
})
`
The problem is here:
setExerciseList({
...doc.data(),
id: doc.id,
title: doc.exerciseTitle,
});
You're setting exerciseList to be an object, yet your rendering code expects it to be an array:
{exerciseList.length > 0 ? ...
Since you don't define a length property in the object, it ends up always render the <ActivityIndicator />.
What you'll want to do is set the entire array of documents in the state, for example with:
const getExercise = async() => {
const querySnapshot = await getDocs(collection(db, "Exercise"));
setExerciseList(querySnapshot.docs.map((doc) => {
return { ...doc.data(), id: doc.id };
});
};
I am getting this warning.
Warning: Cannot update a component (Categoriess) while rendering a different component (CellRenderer). To locate the bad setState() call inside, follow the stack trace as described in https://reactjs.org/link/setstate-in-render%60
I tried too much to fix this issue but I can't. Can anyone please solve this issue?
my code:
`
import { DrawerActions, useNavigation } from '#react-navigation/native';
import { Divider, NativeBaseProvider } from 'native-base';
import fetch from 'node-fetch';
import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
FlatList,
StyleSheet, Text, TouchableOpacity, View
} from 'react-native';
import AntDesign from 'react-native-vector-icons/AntDesign';
import { API_KEY, URL } from '../../globalVariable';
const Categoriess = () => {
const [data, setData] = useState([]);
const [homeID, setHomeId] = useState([]);
const [loading, setLoading] = useState(true)
const navigation = useNavigation();
const option = () => {
let url = `${URL}/store-api/category`;
let options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
'sw-access-key': `${API_KEY}`,
},
};
fetch(url, options)
.then(res => res.json())
.then(json => {
setData(!!json?.elements ? json.elements : [])
setLoading(false)
})
.catch(err => { });
};
useEffect(() => {
option();
}, []);
return (
<View >
<TouchableOpacity
onPress={() => navigation.dispatch(DrawerActions.closeDrawer())}>
<View style={styles.closeDrawer}>
<Text style={styles.text}>Close Menu</Text>
<AntDesign name='close' size={30} />
</View>
</TouchableOpacity>
<Text style={{ fontSize: 25, fontWeight: 'bold', textAlign: 'center' }}>
Categories
</Text>
{
loading ? <ActivityIndicator /> : <FlatList
data={data}
initialNumToRender={7}
renderItem={({ item }) => {
{
if (item.level === 1 && item.afterCategoryId === null) {
setHomeId(item.id);
}
}
const newLocal =
item.level === 2 && item.parentId === homeID ? item.parentId : '';
return (
<View >
<View>
<View>
{item.visible === true && item.parentId === newLocal ? (
<View>
<TouchableOpacity
onPress={() => navigation.navigate('Products', item)}>
<Text style={styles.category}>{item.name}</Text>
<NativeBaseProvider>
<Divider thickness={3} bg="red.200" />
</NativeBaseProvider>
</TouchableOpacity>
{data.map((curElem, index) => {
return item.id === curElem.parentId ? (
<TouchableOpacity
key={index}
onPress={() =>
navigation.navigate('Products', curElem)
}>
<Text style={styles.subCategory}>
- {curElem.name}
</Text>
<NativeBaseProvider>
<Divider thickness={1} />
</NativeBaseProvider>
</TouchableOpacity>
) : null;
})
}
</View>
) : null}
</View>
</View>
</View>
);
}}
/>
}
</View>
);
};
export default Categoriess;
const styles = StyleSheet.create({
category: {
marginHorizontal: 15,
marginVertical: 5,
paddingVertical: 10,
fontSize: 18,
color: '#6779b4',
fontFamily: "Montserrat-Bold"
},
subCategory: {
marginLeft: 30,
marginBottom: 10,
fontSize: 15,
paddingVertical: 10,
fontFamily: "Montserrat-Bold"
},
closeDrawer: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingVertical: 5,
},
text: {
fontSize: 18,
fontFamily: "Montserrat-Bold"
},
});
`
Check this part in renderItem prop. This issue often happens when you trying setState something inside render function
if (item.level === 1 && item.afterCategoryId === null) {
setHomeId(item.id);
}
Looks like you shouldn't store this value in state. Just check it in every renderItem will be enough. FlatList optimisations do all other work well.
const homeID = item.level === 1 && item.afterCategoryId === null ? setHomeId(item.id) : null;
As example
i want to do paging but i cant limit the item to 10. this code shows all the items.
these are not working as well -initialNumToRender,maxToRenderPerBatch,windowSize
<FlatList
data={DATA}
renderItem={({ item }) => (
<Item title={item.name} />
)}
keyExtractor={item => item.id}
ItemSeparatorComponent={ItemSeparatorView}
initialNumToRender={11}
maxToRenderPerBatch={5}
windowSize={2}
/>
Try this,
import React, {useState, useEffect} from 'react';
//import all the components we are going to use
import {
SafeAreaView,
View,
Text,
TouchableOpacity,
StyleSheet,
FlatList,
ActivityIndicator,
} from 'react-native';
const App = () => {
const [loading, setLoading] = useState(true);
const [dataSource, setDataSource] = useState([]);
const [offset, setOffset] = useState(1);
useEffect(() => getData(), []);
const getData = () => {
console.log('getData');
setLoading(true);
//Service to get the data from the server to render
fetch('https://aboutreact.herokuapp.com/getpost.php?offset='
+ offset)
//Sending the currect offset with get request
.then((response) => response.json())
.then((responseJson) => {
//Successful response
setOffset(offset + 1);
//Increasing the offset for the next API call
setDataSource([...dataSource, ...responseJson.results]);
setLoading(false);
})
.catch((error) => {
console.error(error);
});
};
const renderFooter = () => {
return (
//Footer View with Load More button
<View style={styles.footer}>
<TouchableOpacity
activeOpacity={0.9}
onPress={getData}
//On Click of button load more data
style={styles.loadMoreBtn}>
<Text style={styles.btnText}>Load More</Text>
{loading ? (
<ActivityIndicator
color="white"
style={{marginLeft: 8}} />
) : null}
</TouchableOpacity>
</View>
);
};
const ItemView = ({item}) => {
return (
// Flat List Item
<Text
style={styles.itemStyle}
onPress={() => getItem(item)}>
{item.id}
{'.'}
{item.title.toUpperCase()}
</Text>
);
};
const ItemSeparatorView = () => {
return (
// Flat List Item Separator
<View
style={{
height: 0.5,
width: '100%',
backgroundColor: '#C8C8C8',
}}
/>
);
};
const getItem = (item) => {
//Function for click on an item
alert('Id : ' + item.id + ' Title : ' + item.title);
};
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<FlatList
data={dataSource}
keyExtractor={(item, index) => index.toString()}
ItemSeparatorComponent={ItemSeparatorView}
enableEmptySections={true}
renderItem={ItemView}
ListFooterComponent={renderFooter}
/>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
flex: 1,
},
footer: {
padding: 10,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
},
loadMoreBtn: {
padding: 10,
backgroundColor: '#800000',
borderRadius: 4,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
btnText: {
color: 'white',
fontSize: 15,
textAlign: 'center',
},
});
export default App;
I am working on todo list in native , i have a function called onDelete but when i click on it , it delete all element in list and after then program crashed.
this is my main file where i have stored value as key , value pair
export default function App() {
const [courseGoal, setCourseGoal] = useState([]);
const [count, setCount] = useState('');
const submitHandler = () => {
setCourseGoal((currGoal) => [
...currGoal,
{ key: Math.random().toString(), value: count },
]);
};
console.log('App', courseGoal)
return (
<View style={styles.container}>
<SearchBar
setCourseGoal={setCourseGoal}
count={count}
setCount={setCount}
submitHandler={submitHandler}
/>
<ListItem courseGoal={courseGoal} setCourseGoal={setCourseGoal} courseGoal={courseGoal}/>
</View>
);
}
this is my list component where i am facing issue, you can see ondelete here.
import React from "react";
import { StyleSheet, Text, TouchableOpacity } from "react-native";
import { FlatList } from "react-native-web";
export default function ListItem(props) {
const onDelete = (goalId) => {
props.setCourseGoal((currGoal) => {
currGoal.filter((goal) => goal.key !== goalId);
console.log("clicked", props.courseGoal[0].key);
});
};
return (
<FlatList
data={props.courseGoal}
keyExtractor={(item, index) => item.key}
renderItem={(itemData) => (
<TouchableOpacity
onPress={onDelete.bind(itemData.item.key)}
activeOpacity={0.2}
>
<Text style={styles.listData}>{itemData.item.value}</Text>
{console.log(itemData.item.key)}
</TouchableOpacity>
)}
/>
);
}
this is my main component where i have my search input
import React from "react";
import { View, Text, StyleSheet, Pressable, TextInput } from "react-native";
export default function SearchBar(props) {
const onInputHandler = (value) => {
props.setCount(value);
};
return (
<View style={styles.searchBox}>
<Pressable style={styles.submitBtn} title="Click Me !">
<Text>☀️</Text>
</Pressable>
<TextInput
style={styles.searchInput}
placeholder="Enter Goal"
onChangeText={onInputHandler}
/>
<Pressable
style={styles.submitBtn}
title="Click Me !"
onPress={props.submitHandler}
>
<Text>🔥🔥</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
searchBox: {
flexDirection: "row",
justifyContent: "space-around",
},
searchInput: {
width: "90%",
textAlign: "center",
padding: 10,
// color: 'white',
borderRadius: 10,
borderWidth: 1,
marginHorizontal: 5,
},
submitBtn: {
color: "black",
justifyContent: "space-around",
padding: 10,
borderRadius: 10,
borderWidth: 1,
},
});
You have to return the filtered array from your onDelete function
const onDelete = (goalId) => {
props.setCourseGoal((currGoal) => {
return currGoal.filter((goal) => goal.key !== goalId);
});
};