I am trying to get accustomed with React Native. Currently I have these nested FlatLists (where the first level displays a list of RenderedOrders, whereas these RenderedOrders themselves have a FlatList within them).
This is the main screen:
const ActiveScreen = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
const [isLoadingApi, setLoadingApi] = useState(true);
const [orderData, setOrderData] = useState([])
/* Fetch currently taken orders */
useEffect(() => {
getTakenOrders()
.then((data) => setData(data))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
/* Fetch order info from API */
useEffect(() => {
fetch('https://alessandro-visualizr.herokuapp.com/api/orders/NEFACTURAT')
.then((response) => response.json())
.then((json) => setOrderData(json))
.catch((error) => console.error(error))
.finally(() => setLoadingApi(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading || isLoadingApi ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (RenderedOrder(item, orderData)) }
/>
)}
</View>
);
}
export default ActiveScreen;
While this is the above-mentioned component:
import React, {useEffect, useState} from "react";
import {FlatList, Text, View} from "react-native";
import {removeTakenOrder} from "../screens/OrderScreen";
function RenderedOrder(orderId, orderData) {
const [triggered, setTriggered] = useState(true);
return (
<View
style={{ flex: 1}}
>
<View
style={{ fontSize: 20, borderRadius: 5, borderWidth: 1,
marginBottom: 10, padding: 10, backgroundColor: 'rgba(34, 139, 34, 0.75)', color: 'black',
flex: 1 }}
>
<Text
style={{ fontSize: 24 }}
>
#{orderId}
</Text>
<View
style={{ alignItems: 'flex-end' }}
>
<Text
style={{ fontWeight: 'bold', color: 'red', fontSize: 20 }}
onPress={() => removeTakenOrder(orderId)
.then(() => alert("Order #" + orderId + " has been removed"))
}
>
X
</Text>
</View>
</View>
{true &&
<FlatList
data={orderData.filter((order) => (order.orderId === orderId))[0].products}
keyExtractor={({ id }, index) => id}
listKey = {orderId}
renderItem={({ item }) => (
<View>
<Text
style={{ fontSize: 18, padding: 5 }}
>
- {item.name}
<Text style={{ fontWeight: 'bold' }}> x{item.quantity} </Text>
</Text>
</View>
)}
/>
}
</View>
);
}
export default RenderedOrder;
However, when running this example I am confronted with this issue (due to RenderedOrder's state declaration):
Invalid hook call. Hooks can only be called inside the body of a function component.
I understand that in React, states can only be used within function and not class components. However I admit the differences between these two are not that clear to me. Am I commiting a mistake here?
You are using RenderedOrder as function instead of a functional component :
Change this:
renderItem={({ item }) => (RenderedOrder(item, orderData)) }
To this:
renderItem={({ item }) => <RenderedOrder item={item} orderData={orderData} /> }
Related
I am using react native thunder push where continually value fluctuation happening and i am showing data on screen using mobx state management tool. all things is working fine but when i am leave the screen for 2 minute then that events are not working screen is not freezing only events is not working.
STORE
import {observable,action,makeAutoObservable} from 'mobx';
class CommonMob {
data =[];
checkAppstate ='active';
deployeStatus = true;
queryString = '?creator_id=null&tags=&exchange=null&broker_id=null&instrument_type=null&execution=null&status=null&pnl=null&broker_id=';
userToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGktYXBwLnRyYWRldHJvbi50ZWNoXC9hdXRoXC9zaWduLWluIiwiaWF0IjoxNjU0ODYzMjcyLCJleHAiOjIzNTQ3MDMyNzIsIm5iZiI6MTY1NDg2MzI3MiwianRpIjoicVF6TTJHUkdQS3kyY0NCeCIsInN1YiI6MjY3NTE5LCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.QLDx1SUEJBheQbm-UqD8AOad5Oj3x3UWHBeShmn-2PE';
constructor() {
makeAutoObservable(this)
}
setData(res) {
this.data =res;
}
setAppState(val){
this.checkAppstate = val;
}
setdeployeStatus(val){
this.deployeStatus = val;
}
}
export default new CommonMob()
Screen
import {TouchableOpacity,View, Text, Button, FlatList, AppState,ScrollView,InteractionManager} from 'react-native';
import React, {useCallback, useEffect} from 'react';
import deployedStore from '../mob/deployedStore';
import {useIsFocused, useFocusEffect} from '#react-navigation/native';
import MarketStore from '../mob/deployedStore';
import {observer} from 'mobx-react-lite';
import {initThunderPush} from '../Service/ThunderConnection';
import {
fetchStrategies,
fetchFullStrategies,
} from '../Service/DeployeConnection';
import CommonStore from '../mob/commonStore';
import commonStore from '../mob/commonStore';
import Nav from '../Nav/Nav';
import { useNavigation } from '#react-navigation/native';
// import commonStore from '../mob/commonStore';
let listening = false;
const Deplyee = React.memo(observer(({navigation}) => {
// const navigation = useNavigation();
const navFun = ()=>{
alert("function call");
navigation.navigate("Dashboard")
}
useFocusEffect(
useCallback(() => {
// Do something when the screen is focused.
deployedStore.setisDeploye(true);
deployedStore.setisMarcketWatch(true);
commonStore.setdeployeStatus(true);
return () => {
// Do something when the screen is unfocused
deployedStore.setisDeploye(false);
deployedStore.setisMarcketWatch(false);
commonStore.setdeployeStatus(false);
};
}, []),
);
// React.useEffect(() => {
// }, [deployedStore.dataaa, deployedStore.strategies]);
React.useEffect(
() => {
InteractionManager.runAfterInteractions(() => {
// let timer = setTimeout(() => , 1000)
fetchFullStrategies(CommonStore.userToken);
fetchStrategies();
// fetchFullStrategies(CommonStore.userToken);
initThunderPush();
return () => {
clearTimeout(timer)
}
});
},
[[deployedStore.dataaa, deployedStore.strategies]]
)
React.useEffect(() => {
fetchStrategies();
}, [deployedStore.strategies]);
useFocusEffect(
React.useCallback(() => {
// fetchFullStrategies(CommonStore.userToken);
}, [deployedStore.strategies]),
);
React.useEffect(
() => {
if (!listening) {
initThunderPush();
listening = true;
}
setInterval(() => {
deployedStore.setCanState(true);
}, 1000);
},
[
/*strategies*/
],
);
useEffect(() => {
const appStateListener = AppState.addEventListener(
'change',
nextAppState => {
commonStore.setAppState(nextAppState);
},
);
return () => {
appStateListener?.remove();
};
}, []);
return (
<View>
<ScrollView>
<View
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
margin: 'auto',
flexWrap: 'wrap',
}}>
<Nav />
<TouchableOpacity onPress={() => alert("test pass")} ><Text>Test alert</Text></TouchableOpacity>
<TouchableOpacity onPress={() => navFun()} >
<Text>test function </Text>
</TouchableOpacity>
</View>
<Text>Deployed Strategies</Text>
{deployedStore.strategies.map(item => (
<View key={item.identifier}>
<Text style={{color: 'red', alignSelf: 'center'}}>
NAME - {item.template.name}
</Text>
<Text style={{color: 'blue', alignSelf: 'center'}}>
TYPE - {item.deployment_type}
</Text>
<Text style={{color: 'green', alignSelf: 'center'}}>
STATUS {item.status}
</Text>
<Text style={{color: 'orange', alignSelf: 'center', fontSize: 20}}>
{/* <Text style={item.sum_of_pnl >= 0 ? {color:green} : {color:red}}> */}
{item.country === 'IN'
? `${(item.sum_of_pnl, 0)} (${(
(item.sum_of_pnl /
(item.template.capital_required * item.minimum_multiple)) *
100
).toFixed(2)} %)`
: null}
</Text>
{/* <Text style={{color:'green', alignSelf:'center'}}>{item.ltp}</Text> */}
</View>
))}
<Text>market watch section</Text>
{deployedStore.dataaa.map(item => (
<View key={item.identifier}>
<Text style={{color: 'red', alignSelf: 'center'}}>
{item.identifier}
</Text>
<Text style={{color: 'green', alignSelf: 'center'}}>{item.ltp}</Text>
</View>
))}
</ScrollView>
</View>
);
}));
export default React.memo(Deplyee);
Im working on a react-native project and what I'm trying to do is for the user to have the possibility to select phone numbers in his contact list.
When the user selects one or more contacts, the app won't work, and it shows this error on the console: VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc.
ContactList.js
unction ContactList() {
const [refreshing, setRefreshing] = React.useState(false);
const [itemChecked, setItemChecked] = useState([]);
const [checked, setChecked] = useState(new Map());
const [contacts, setContacts] = useState([]);
const [filter, setFilter] = useState([]);
const [search, setSearch] = useState('');
const [data, setData] = useState(filter)
useEffect(() => {
(async () => {
const { status } = await Contacts.requestPermissionsAsync();
if (status === 'granted') {
const { data } = await Contacts.getContactsAsync({
fields: [Contacts.Fields.PhoneNumbers],
// fields: [Contacts.Fields.Name],
});
if (data.length > 0) {
setContacts(data);
setFilter(data);
// console.log('contact', contacts[1]);
// console.log('filter', filter);
}
}
})();
}, []);
const searchFilter = (text) => {
if (text) {
const newData = contacts.filter((item) => {
const itemData = item.name ? item.name.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setFilter(newData);
setSearch(text);
} else {
setFilter(contacts);
setSearch(text);
}
};
const onChangeValue = (item) => {
checked.set(item, true);
};
useEffect(() => {
checked &&
setData((previous) => [...previous, {phone: contacts} ])
}, [checked],
)
const renderItem = ({ item, index }) => {
return (
<SafeAreaView>
<ScrollView>
<TouchableOpacity style={{ flexDirection: 'row', flex: 1 }}>
<View style={{ flex: 1, borderTopWidth: 0.5, borderTopColor: 'grey', marginBottom: 15 }}>
<Text onPress={() => setChecked(true)} style={{ fontSize: 20, marginHorizontal: 10 }}>
{item.name + ' '}
</Text>
<Text style={{ fontSize: 17, marginHorizontal: 10, marginTop: 5, color: 'grey' }}>
{item.phoneNumbers && item.phoneNumbers[0] && item.phoneNumbers[0].number}
</Text>
</View>
<View style={{ flex: 1, borderTopWidth: 0.5, borderTopColor: 'grey' }}>
<CheckBox
style={{ width: 15, height: 15 }}
right={true}
checked={checked.get(index)}
onPress={()=> onChangeValue(index)}
/>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.container}>
<View
style={{
height: 40,
justifyContent: 'center',
backgroundColor: '#EEEEEE',
width: '90%',
marginHorizontal: 20,
marginTop: 15,
borderRadius: 10,
}}
>
<Feather name="search" size={20} color="grey" style={{ position: 'absolute', left: 32 }} />
<TextInput
placeholder="Search"
placeholderTextColor="#949494"
style={{
left: 20,
paddingHorizontal: 35,
fontSize: 20,
}}
value={search}
onChangeText={(text) => {
searchFilter(text);
setSearch(text);
}}
/>
</View>
<FlatList
style={{ marginTop: 15 }}
data={contacts && filter}
keyExtractor={(item) => `key-${item.id.toString()}`}
renderItem={renderItem}
ListEmptyComponent={<Text message="No contacts found." />}
/>
</View>
</SafeAreaView>
);
}
export default ContactList;
How can I solve this bug?
I am trying to make a stack navigator using reactstack navigation. When the button clicks, it appears on the detail screen only, the title of the page is detail. I am not yet to parsing data array to the next screen, it just tries to navigate the screen into the detail screen, and gets this error. I am new to react. Please help me solve this problem.
import React from 'react'
import {Button, StyleSheet, ScrollView, Text, View} from 'react-native'
import {useState, useEffect} from 'react'
import axios from 'axios'
const Item = ({id, user_id, title, onPress, navigation}) => {
return (
<View style={styles.container}>
<Text style={styles.text}>Id :{id}
</Text>
<Text style={styles.text}>User Id :{user_id}
</Text>
<Text style={styles.text}>Tittle :{title}
</Text>
<View style={styles.container}>
<Button onPress={() => navigation.navigate('Detail')} title='Detail'></Button>
</View>
<View style={styles.line}></View>
</View>
)
}
const Berita = () => {
const [users,
setUsers] = useState([]);
useEffect(() => {
getData();
}, []);
const selectItem = (item) => {
console.log('Selected item: ', item)
}
const getData = () => {
axios
.get('https://gorest.co.in/public/v1/posts')
.then(res => {
console.log('res: ', res);
setUsers(res.data.data);
})
}
return (
<ScrollView style={styles.container}>
{users.map(user => {
return <Item key={user.id} id={user.id} user_id={user.user_id} title={user.title}/>
})}
</ScrollView>
)
}
export default Berita
const styles = StyleSheet.create({
container: {
padding: 15
},
text: {
color: "black",
marginTop: 5,
fontStyle: 'italic',
fontSize: 18,
fontFamily: 'Arial'
},
line: {
height: 1,
backgroundColor: 'black',
marginVertical: 20
},
title: {
fontSize: 25,
fontWeight: 'bold',
textAlign: 'center',
color: "black"
},
tombol: {
padding: 10
}
})
This is the stack screen navigator code
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
const DetailBerita = () => {
return (
<Stack.Navigator >
<Stack.Screen
name='Berita'
component={Berita}
options={{
headerTitleAlign: 'center'
}}/>
<Stack.Screen
name="Detail"
component={Detail}
options={{
headerTitleAlign: 'center'
}}/>
</Stack.Navigator>
)
}
It appears that you are using Stack Navigators with different screen names, but you didn't send it. If possible, can you send that file, I would be able to help you a bit better. But from what I have I can try and explain how Stack navigation works. With this line of code:
navigation.navigate('Detail')
You specify that you want to navigate to the screen named "Detail", if you want to navigate to another screen then you can change it to the name of the screen. Let's say you want to navigate to your home screen, and its named "Home" in your Stack.Navigation component. Simply change your navigation to the following:
navigation.navigate('Home')
This is happening because the navigation prop is passed to the Berita component and you are destructuring the property in Item component not in Berita.
So the code should look like
...
const Berita = ({ navigation }) => {
// ...
return (
<ScrollView style={styles.container}>
{users.map(user => {
return (
<Item
key={user.id}
id={user.id}
user_id={user.user_id}
title={user.title}
navigation={navigation} // Pass navigation
/>
);
})}
</ScrollView>
);
};
Another way is - you can just use navigation in onPress (Berita) and pass down onPress to Item component
const Item = ({ id, user_id, title, onPress }) => {
return (
<View style={styles.container}>
<Text style={styles.text}>Id :{id}</Text>
<Text style={styles.text}>User Id :{user_id}</Text>
<Text style={styles.text}>Tittle :{title}</Text>
<View style={styles.container}>
<Button onPress={onPress} title="Detail" />
</View>
<View style={styles.line}></View>
</View>
);
};
const Berita = ({ navigation }) => {
const [users, setUsers] = useState([]);
useEffect(() => {
getData();
}, []);
const selectItem = item => {
console.log('Selected item: ', item);
};
const getData = () => {
axios.get('https://gorest.co.in/public/v1/posts').then(res => {
console.log('res: ', res);
setUsers(res.data.data);
});
};
return (
<ScrollView style={styles.container}>
{users.map(user => {
return (
<Item
key={user.id}
id={user.id}
user_id={user.user_id}
title={user.title}
onPress={() => navigation.navigate('Detail')}
/>
);
})}
</ScrollView>
);
};
I'm making a search bar that displays results live. I've managed to do it properly utilizing SearchBar from 'react-native-elements'. Firstly I had it written as a class component, but decided to rewrite it as a functional component. After rewriting it I'm encountering a bug where the keyboard closes after one letter as seen in the video here
Here is the code of the component
import React, { Component, useEffect, useState } from "react";
import { View, Text, FlatList, TextInput, ListItem } from "react-native";
import { SearchBar } from "react-native-elements";
import { Button } from 'react-native-paper'
import Header from "../navigation/Header";
export default function AktSelect() {
const [data, setData] = useState([])
const [value, setValue] = useState('')
const [akt, setAkt] = useState([])
useEffect(() => {
fetch("http://192.168.5.12:5000/aktprikaz", {
method: "get"
})
.then(res => res.json())
.then(res => setAkt(res));
}, []);
function renderSeparator() {
return (
<View
style={{
height: 1,
width: "100%",
backgroundColor: "#CED0CE"
}}
/>
);
}
function searchItems(text) {
const newData = akt.filter(item => {
const itemData = `${item.title.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setData(newData)
setValue(text)
}
function renderHeader() {
return (
<SearchBar
placeholder=" Type Here...Key word"
onChangeText={text => searchItems(text)}
value={value}
lightTheme={true}
/>
);
}
return (
<View
style={{
flex: 1,
width: "98%",
alignSelf: "center",
justifyContent: "center"
}}
>
<Header title='Pretraživanje aktivnosti' />
<FlatList
data={data}
renderItem={({ item }) => (
<View style={{flex: 1}}>
<Text style={{ padding: 10 }}>{item.title} </Text>
<View style={{flexDirection:'row'}}>
<Text style={{ padding: 10 }}>{item.start_time} </Text>
<Button style={{justifyContent: 'flex-end', alignContent: 'flex-end', width:'30%'}} mode='contained' onPress={() => console.log('hi')}>hi</Button>
</View>
</View>
)}
keyExtractor={item => item.id.toString()}
ItemSeparatorComponent={renderSeparator}
ListHeaderComponent={renderHeader}
/>
</View>
);
}
The old class component can be found here
Code :
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button, TextInput, ScrollView, FlatList } from 'react-native';
import GoalItem from './components/GoalItem';
export default function App() {
const [enteredGoal, setEnteredGoal] = useState('');
const [courseGoals, setCourseGoals] = useState([]);
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
const addGoalHandler = () => {
//console.log(enteredGoal);
setCourseGoals(currentGoals => [...currentGoals, { id: Math.random().toString(), value: enteredGoal }]);
};
return (
<View style={styles.screen}>
<View style={styles.inputContainer}>
<TextInput placeholder="Course Goal" style={styles.input}
onChangeText={goalInputHandler} value={enteredGoal} />
<Button title="Add" onPress={addGoalHandler} />
</View>
<FlatList keyExtractor={(item, index) => item.id} data={courseGoals}
renderItem={itemData => <GoalItem title={itemData.item.value} />}
/>
</View>
);
}
const styles = StyleSheet.create({
screen: {
padding: 50
},
inputContainer: {
flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'
},
input: {
width: '70%', borderBottomColor: 'black', borderWidth: 1, padding: 10
},
});
GoalItem Components :
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const GoalItem = props => {
return (
<View style={styles.listItem}>
<Text>{props.title}</Text>
</View>
);
};
const styles = StyleSheet.create({
listItem: {
padding: 10, backgroundColor: '#ccc', borderColor: 'black', borderWidth: 1, marginVertical: 10
}
});
export default GoalItem;
Error : Below is the code, please check Can't find variable itemData
in react-native
Pls i am a newbie in react-native i just got for about two hours. Any
help would be appreciated. Thanks in advance. Look into the code and share some advice so that the code works well..
Thanks :)
It should be
<FlatList keyExtractor={(item, index) => item.id}
data={courseGoals}
renderItem={(itemData) => <GoalItem title={itemData.item.value} }/>
Or
<FlatList keyExtractor={(item, index) => item.id}
data={courseGoals}
renderItem={({item}) => <GoalItem title={item.value} }/>
it should be like this :
<FlatList
data={courseGoals}
renderItem={itemData => (
<View style={styles.listItem}>
<Text>{itemData.item}</Text>
</View>
)}
/>