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>
)}
/>
Related
I'm trying to make an app similar to a chatting service in react-native.
I have 3 files: fpLogin(Login page), ChatsScreen(The screen where you can see all of your active chats), ChatsComponent(I'm passing chats in chatsScreen as chatsComponent as it seems more efficient to me)
It's still a work in progress but I keep getting stuck on this one error which says: "Cannot read properties of undefined (reading 'width')
Would be much appreciated if someone could help me out here as I am stuck on this for about 3 days now...
fpLogin
import React, { useState } from "react";
import {
Text,
View,
Button,
StyleSheet,
TextInput,
ImageBackground,
} from "react-native";
const fpLogin = ({ navigation }) => {
const [username, setUsername] = useState("");
const [password, setPasword] = useState("");
const flag = false;
return (
<ImageBackground
style={styles.background}
source={require("../../assets/background.jpg")}
>
<View>
<Text style={styles.mid}>Login page</Text>
<TextInput
style={styles.textBox}
placeholder={"Enter Username"}
autoCapitalize="none"
autoCorrect={false}
value={username}
onChangeText={(newValue) => setUsername(newValue)}
/>
<TextInput
style={styles.textBox}
placeholder={"Enter Password"}
autoCapitalize="none"
autoCorrect={false}
secureTextEntry={true}
value={password}
onChangeText={(newValue) => setPasword(newValue)}
/>
<Button title="Login" onPress={() => navigation.navigate("Chat")} />
</View>
</ImageBackground>
);
};
styles = StyleSheet.create({
mid: {
fontSize: 50,
textAlign: "center",
},
textBox: {
fontSize: 30,
textAlign: "center",
borderWidth: 3,
borderColor: "black",
margin: 20,
},
background: {
flex: 1,
width: null,
},
});
export default fpLogin;
ChatsScreen
import React from "react";
import { View, Text, Button, StyleSheet, ImageBackground } from "react-native";
import ChatsComponent from "../components/ChatsComponent";
const ChatsScreen = () => {
return (
<View>
<ImageBackground
source={require("../../assets/background.jpg")}
style={styles.background}
/>
<ChatsComponent name="Jannet" />
<ChatsComponent name="Mike" />
<ChatsComponent name="Adam" />
<ChatsComponent name="Ofek" />
<ChatsComponent name="Matti" />
<ChatsComponent name="Yaniv" />
<ChatsComponent name="Shani" />
<ChatsComponent name="Noy" />
<ChatsComponent name="Paul" />
<ChatsComponent name="Daniel" />
</View>
);
};
styles = StyleSheet.create({
background: {
flex: 1,
},
});
export default ChatsScreen;
ChatsComponent
import React from "react";
import { View, Text, Button, StyleSheet, TouchableOpacity } from "react-native";
const Chats = ({ name }) => {
return (
<View>
<TouchableOpacity style={styles.buttonFacebookStyle}>
<Text style={styles.nameStyle}>{name}</Text>
</TouchableOpacity>
</View>
);
};
styles = StyleSheet.create({
buttonFacebookStyle: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "#485a96",
borderWidth: 0.5,
borderColor: "#fff",
height: 40,
width: null,
borderRadius: 4,
margin: 5,
},
nameStyle: {
alignContent: "center",
},
});
export default Chats;
This is the ERROR screen I am getting on my npm
https://i.stack.imgur.com/INV6P.jpg
Thanks in advance to anyone who is willing to help :)
I think you need to explicitely set the size of ImageBackground try:
<ImageBackground
style={styles.background}
source={require("../../assets/background.jpg")}
>
...
...
background: {
flex: 1,
width: '100%',
height: '100%',
resizeMode: 'cover'}
You are not declaring styles as constant.
Try to use it like this:
const styles = StyleSheet.create({
`enter your style here`
})
Also, you can use width directly without calling on style prop. ImageBackground has width and height API.
<ImageBackground
width={'100%'}
height={'100%'}>
`you can use width and height`
</ImageBackground>
I am new to react and react native technology and I am stuck into a warning which I am not able to solve.
Two warnings I get:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it
indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method in PhoneInput (at Login.js:40)
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it
indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function in CountryPicker.
Here is my Login.js
import React, {useEffect, useState, useRef } from "react";
import {
View, Text,TouchableOpacity,
StyleSheet, Image, SafeAreaView,
TextInput,
StatusBar, ScrollView
} from 'react-native';
import { Card } from "react-native-shadow-cards";
import PhoneInput from 'react-native-phone-number-input';
import Styling from "../components/Styling";
const Login = (props) => {
const phoneInput = useRef(PhoneInput > (null));
const [phoneNumber,setphoneNumber]=useState(null);
return (
<View style={styles.container}>
<StatusBar backgroundColor='#1e3d59' barStyle="light-content" />
<ScrollView>
<View style={styles.header}>
<Image source={require('../assets/images/login.png')}
style={{ height: 150, width: 150, }}></Image>
</View>
<View
style={[styles.footer]}>
<Text style={Styling.text_footer}>Mobile Number</Text>
<View style={{marginTop:10,
alignContent:'center',
alignItems:'center',
paddingLeft:15,
borderWidth:1,
borderColor:'#d7dade',
borderRadius:20,
flexDirection:'row',
height:72,}}>
<SafeAreaView >
<PhoneInput
containerStyle={{
backgroundColor: '#fff',
borderColor:'black',
alignContent:'center',
height:70,
}}
flagButtonStyle={{
width:'15%'
}}
textContainerStyle={{
backgroundColor: '#fff',
}}
ref={phoneInput}
defaultValue={phoneNumber}
defaultCode="IN"
layout="first"
keyboardType='numeric'
onChangeText={setphoneNumber}
></PhoneInput>
</SafeAreaView>
</View>
<TouchableOpacity on onPress={() => props.onSubmit('+91'+phoneNumber)}>
<Card style={[containerStyle={
height:50,
elevation:0,
borderRadius:10,
backgroundColor: '#ff6e40',
width:"100%",
alignItems:'center',
alignContent:'center',
justifyContent:'center'
},{marginTop:30}]}>
<View >
<Text style={[Styling.textSign, {color:'#fff'}]}>Request OTP</Text>
</View>
</Card>
</TouchableOpacity>
</View>
</ScrollView>
</View>
);
};
export default Login;
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:"column",
backgroundColor: '#1e3d59',
width: '100%',
},
header: {
alignItems: 'center',
height:"50%",
justifyContent:"center"
},
footer: {
backgroundColor: "white",
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
paddingHorizontal: 20,
paddingTop: 20,
paddingBottom:600
},
});
Here is my App.js
import React, { useState } from 'react';
import auth from '#react-native-firebase/auth';
import VerifyCode from './src/screens/VerifyCode';
import AuthStack from './src/navigation/AuthStack';
import Login from './src/auth/Login';
import { NavigationContainer } from '#react-navigation/native';
const App = () => {
const [confirm, setConfirm] = useState(null);
const [authenticated, setAuthenticated] = useState(false);
const signIn = async (phoneNumber)=> {
try {
const confirmation = await auth().signInWithPhoneNumber(phoneNumber);
setConfirm(confirmation);
} catch (error) {
alert(error);
}
}
const confirmVerificationCode= async (code) =>{
try {
await confirm.confirm(code);
setConfirm(null);
} catch (error) {
alert('Invalid code');
}
}
auth().onAuthStateChanged((user) => {
if(user) {
setAuthenticated(true);
} else {
setAuthenticated(false);
}
})
return(
<NavigationContainer>
{ authenticated? (
<AuthStack/>
)
:
confirm? (
<VerifyCode onSubmit={confirmVerificationCode}/>
)
:
<Login onSubmit={signIn}/>
}
</NavigationContainer>
);
}
export default App;
Here is my VerifyCode.js
import React, { useState} from "react";
import {
View, Text,Platform, TouchableOpacity,
StyleSheet, Image,
TextInput,
StatusBar, ScrollView
} from 'react-native';
import { Card } from "react-native-shadow-cards";
import Styling from "../components/Styling";
const Login = (props) => {
const [code, setCode] = useState('');
return (
<View style={styles.container}>
<StatusBar backgroundColor='#1e3d59' barStyle="light-content" />
<ScrollView>
<View style={styles.header}>
<Image source={require('../assets/images/login.png')}
style={{ height: 150, width: 150, }}></Image>
</View>
<View
style={[styles.footer]}>
<View style={{marginTop:10,
alignContent:'center',
alignItems:'center',
alignSelf:'center',
justifyContent:"center",
borderWidth:1,
borderColor:'#d7dade',
borderRadius:20,
height:60,
width:"40%"
}}>
<TextInput
placeholder="Enter OTP"
autoFocus
value={code}
onChangeText={setCode}
keyboardType="numeric"
style={{fontSize:20,}}
></TextInput>
</View>
<View style={{width:"100%", alignSelf:"center"}}>
<TouchableOpacity on onPress={() => props.onSubmit(code)}>
<Card style={[containerStyle={
height:50,
elevation:0,
borderRadius:10,
backgroundColor: '#ff6e40',
alignItems:'center',
alignContent:'center',
justifyContent:'center'
},{marginTop:20}]}>
<View >
<Text style={[Styling.textSign, {color:'#fff'}]}>Confirm</Text>
</View>
</Card>
</TouchableOpacity>
</View></View>
</ScrollView>
</View>
);
};
export default Login;
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:"column",
backgroundColor: '#1e3d59',
width: '100%',
},
header: {
alignItems: 'center',
justifyContent:"center",
height:"50%"
},
footer: {
backgroundColor: "white",
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
paddingHorizontal: 20,
paddingTop: 20,
paddingBottom:600
},
});
This is my app.js
the main body of my app.
...
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
Button,
TextInput,
FlatList,
} from "react-native";
import GoalItem from "./components/GoalItem";
import GoalInput from "./components/GoalInput";
export default function App() {
const [lifeGoals, setLifeGoals] = useState([]);
const addGoalHandler = (goalTitle) => {
setLifeGoals((currentGoals) => [
...currentGoals,
{ key: Math.random().toString(), value: goalTitle },
]);
};
const removeGoalHandler = (goalId) => {
setLifeGoals((currentGoals) => {
return currentGoals.filter((goal) => goal.id !== goalId);
});
};
return (
<View style={styles.Screen}>
<GoalInput onAddGoal={addGoalHandler} />
<FlatList
keyExtractor={(item, index) => item.id}
data={lifeGoals}
renderItem={(itemData) => (
<GoalItem
id={itemData.item.id}
onDelete={removeGoalHandler}
title={itemData.item.value}
/>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
Screen: {
padding: 50,
},
});
...
This is my GoalItem which houses my list
...
import React from "react";
import { StyleSheet, View, Text, TouchableOpacity } from "react-native";
const GoalItem = (props) => {
return (
<TouchableOpacity onPress={props.onDelete.bind(this, props.id)}>
<View style={styles.ListItem}>
<Text>{props.title}</Text>
</View>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
ListItem: {
padding: 10,
marginVertical: 10,
backgroundColor: "#CCFFFF",
borderRadius: 15,
},
});
export default GoalItem;
...
This is my GoalInput which handles the userinput and appending onto the list
...
import React, { useState } from "react";
import { View, TextInput, Button, Stylesheet, StyleSheet } from "react-native";
const GoalInput = (props) => {
const [enteredGoal, setEnteredGoal] = useState("");
const InputGoalHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
return (
<View style={styles.inputContainer}>
<TextInput
placeholder="Enter Task Here"
style={styles.InputBox}
onChangeText={InputGoalHandler}
value={enteredGoal}
/>
<Button title="add" onPress={props.onAddGoal.bind(this, enteredGoal)} />
</View>
);
};
const styles = StyleSheet.create({
InputBox: {
borderColor: "black",
borderWidth: 0,
padding: 10,
width: "80%",
},
inputContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
},
});
export default GoalInput;
...
I believe that the key might be the issue but i'm really not sure. What's supposed to happen is that when you click on an item in the list, it should be deleted, however it's deleting my whole list. How do i solve this?
const removeGoalHandler = (goalId) => {
setLifeGoals(lifeGoals.filter((m) => m.id !== goalId.id));
};
<FlatList
keyExtractor={(item) => item.id}
data={lifeGoals}
renderItem={(itemData) => (
<GoalItem
onDelete={removeGoalHandler}
title={itemData.item.value}
/>
)}
/>
const GoalItem = ({onDelete, title}) => {
return (
<TouchableOpacity onPress={onDelete}>
<View style={styles.ListItem}>
<Text>{title}</Text>
</View>
</TouchableOpacity>
);
};
try this
Currently, this - is how the SearchBar and FlatList is showing up on the screen. Upon clicking on the SearchBar and typing one of the list components, it shows up this- way. I want the FlatList to only appear when I click on the SearchBar. How do I implement this in the app? Something like a dropdown search bar...
import React from 'react';
import { View, Text, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import { SearchBar } from 'react-native-elements';
import { Button, Menu, Divider, Provider, TextInput } from 'react-native-paper';
const restaurantList = [
{
type: 'Italian',
name: 'DiMaggio'
},
{
type: 'Greek',
name: 'Athena'
}
];
export default class App extends React.Component {
static navigationOptions = {
title: 'Search for Restaurants'
};
constructor (props) {
super(props);
this.state = {
loading: false,
data: restaurantList,
error: null,
value: '',
};
this.arrayholder = [];
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '86%',
backgroundColor: '#CED0CE',
marginLeft: '14%'
}}
/>
);
};
searchFilterFunction = text => {
this.setState({
value: text
});
const newData = restaurantList.filter(item => {
console.log(item.type)
const itemData = `${item.name.toUpperCase()} ${item.type.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.includes(textData);
});
this.setState({
data: newData
});
};
renderHeader = () => {
return (
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
/>
);
};
render () {
if (this.state.loading) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator />
</View>
);
} else {
return (
<Provider>
<View
style={{
paddingTop: 50,
flexDirection: 'row',
justifyContent: 'center',
}}>
<View style={styles.container}>
<FlatList
keyExtractor={(item, index) => `${index}`}
extraData={this.state}
data={this.state.data}
renderItem={({ item }) => (
<Text>{item.name} {item.type}</Text>
)}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
</View>
</View>
<View style={styles.container}>
<TextInput />
</View>
</Provider>
);
}
}
}
Try this way
this.state = {
searchClicked: false
};
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
onFocus={() => this.setState({searchClicked: true})}
onBlur={() => this.setState({searchClicked: false})}
/>
<View>{this.renderHeader()}</View>
{this.state.searchClicked && <FlatList
keyExtractor={(item, index) => `${index}`}
extraData={this.state}
data={this.state.data}
renderItem={({ item }) => (
<Text>{item.name} {item.type}</Text>
)}
ItemSeparatorComponent={this.renderSeparator}
// ListHeaderComponent={this.renderHeader} <—- Remove from here —->
/>}
In case #Lakhani reply doesn't satisfy your question, I have another suggestion for you.
Your SearchBar should contain a TextInput. You can use onFocus and onBlur props to capture event you click on SearchBar or leave it.
...
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
onFocus={()=>this.setState({showList: true})} // <---
onBlur={()=>this.setState({showList: false})} // <---
/>
...
render() {
return (
...
{
this.state.showList && <FlatList ... />
}
)
}
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