React Native--Functional component--useState not working - react-native

My code is:
import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import { StyleSheet, Text, View, Button, TextInput } from "react-native";
export default function App() {
const [entGoal, setEntGoal] = useState("");
const textHandler = (entText) => {
setEntGoal(entText);
};
const addHandler = () => {
console.log(entGoal);
};
return (
<View style={{ margin: 12, padding: 50 }}>
<View>
<Text>Goals List!</Text>
<TextInput
placeholder="Enter Goal"
style={{ borderBottomWidth: 1, borderColor: "black" }}
value={entGoal}
onChange={textHandler}
/>
<Button title="Add (+)" onPress={addHandler} />
</View>
</View>`enter code here`
);
}
I am trying to do a simple code for asking to enter some goals and to print the text in the console as output.
But I am not getting output in the console.
Some long synthetic errors are popped up.

Please go through the TextInput guide, and replace your onChange prop with onChangeText. Like:
<TextInput
placeholder="Enter Goal"
style={{ borderBottomWidth: 1, borderColor: "black" }}
value={entGoal}
onChangeText={textHandler}
/>
Hope this works for you.

Related

items doesnt stick to bottom react nativr

im trying to make a to-do list in react native and im trying to make the input and plus bar stick to the bottom and make it go up when i open the keyboard. when i use padding the bar sticks to bottom but i want to use flexbox to make it compatible with all phones. can someone help make stick it to bottom and make it go up with keyboard
task.js
import React from 'react';
import {View, Text, SafeAreaView, StyleSheet, TextInput,KeyboardAvoidingView, TouchableWithoutFeedback, TouchableOpacity} from 'react-native';
const AddTask = () => {
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task])
setTask(null);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style ={styles.inputbuttons}
>
<TextInput style={styles.input} placeholder={'Write a task'} />
<TouchableOpacity onPress={() => handleAddTask()}>
<View style = {styles.plus}>
<Text>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
input: {
height: 60,
width:320,
margin: 12,
borderWidth: 1,
padding: 10,
borderRadius:20,
},
inputbuttons:{
flexDirection:'row',
alignItems:'center',
justifyContent:'flex-end'
},
plus:{
width:60,
height:60,
borderWidth:1,
borderColor:'black',
textAlign:'right',
borderRadius:'15',
textAlign: 'center',
justifyContent: 'center',
fontSize:30
}
});
export default AddTask;
app.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View,Button, Alert,Input } from 'react-native';
import Task from './components/Task';
import AddTask from './components/AddTask';
export default function App() {
return (
<View style={styles.container}>
<View style = {styles.taskWrapper}>
<Text style={styles.header}>Today's Tasks</Text>
</View>
<View style={styles.tasks}>
<Task></Task>
<Task></Task>
</View>
<View>
<AddTask></AddTask>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#E8EAED',
},
taskWrapper:{
paddingTop:80,
paddingHorizontal:20
},
header:{
fontSize:24,
fontWeight:'bold'
},
tasks:{
},
});
You should use KeyboardAvoidingView in your app component so that whenever keyboard gets activated then the component of App gets pushed.

Error : You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports

I got this error when trying to import and use another component that I have created in another file. And I got an error like this :
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 `Sidebar`.
This is my code to export component as default component in customDrawer.js which file is same directory:
const Sidebar = ({ isDarkTheme, setIsDarkTheme, ...props }) => {
const handlePress = () => {
props.navigation.dispatch(DrawerActions.closeDrawer());
props.navigation.navigate("Settings");
};
const { colors } = useTheme();
const toggleTheme = () => {
setIsDarkTheme();
};
// console.log('navi--?',props.navigation);
return (
<Container style={{ backgroundColor: colors.background }}>
<Header
style={{
backgroundColor: colors.background,
borderBottomWidth: 0,
marginTop: 70,
borderWidth: 0,
}}
>
<StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
<Right>
<Button transparent>
<TouchableOpacity onPress={() => handlePress()}>
{/* <Ionicons name="ios-options" size={28} color={colors.icon} /> */}
</TouchableOpacity>
</Button>
</Right>
</Header>
<Content>
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
</DrawerContentScrollView>
<TouchableOpacity>
<View
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
paddingRight: 20,
paddingLeft: 20,
paddingTop: 10,
}}
>
<Text style={{ flex: 1, color: colors.text }}>Dark Theme</Text>
<View>
<Switch onValueChange={toggleTheme} value={isDarkTheme} />
</View>
</View>
</TouchableOpacity>
</Content>
</Container>
);
};
const styles = StyleSheet.create({});
export default Sidebar;
And then, in my App.js I have import components like this :
import Sidebar from "./customDrawer";
All imports I use in customDrawer.js :
import {
DrawerContentScrollView,
DrawerItemList,
} from "#react-navigation/drawer";
import { Button, Container, Content, Header, Right } from "native-base";
import React, { useState } from "react";
//import { Ionicons } from "#expo/vector-icons";
import { StyleSheet, Text, View, Switch } from "react-native";
import { StatusBar } from "react-native";
import { TouchableOpacity } from "react-native";
import { DrawerActions } from "#react-navigation/native";
import { useTheme } from "#react-navigation/native";

React Native element only visible/usable after pressing a button

New to React Native, having a go at an app idea. Basically I'm just trying to create an TextInput element that appears when I press a Button. Below is my attempt. I'm trying to take advantage of state within my class, but something is off.
Expo is throwing an error of 'null is not an object (evaluating 'this.state.isShowingText')'.
Any ideas?
import React, { Component } from 'react';
import { TextInput, Alert, Button, ScrollView, Text, View, StyleSheet } from 'react-native';
export default class CoolComponent extends Component {
render() {
const nameAdd = () =>{
state = { isShowingText: true };
}
return (
<View style={{ alignItems: 'center', top: 50 }}>
<Title>Some Title</Title>
{this.state.isShowingText ? <TextInput></TextInput> : null}
<ScrollView></ScrollView>
<Button
title="Press me"
onPress={nameAdd}
/>
</View>
);
}
}
The way you handling state is wrong
import React, { Component } from 'react';
import { TextInput, Button, ScrollView, View } from 'react-native';
export default class CoolComponent extends Component {
state = {
isShowingText: false
}
nameAdd = () => {
this.setState({
isShowingText: true
})
}
render() {
return (
<View style={{ alignItems: 'center', top: 50 }}>
{this.state.isShowingText ? <TextInput style={{ width: '50', height: '50', borderWidth: 1 }}></TextInput> : null}
<ScrollView></ScrollView>
<Button
title="Press me"
onPress={this.nameAdd}
/>
</View>
);
}
}
Hope this helps you. Feel free for doubts.

TextInput loses focus after every keystroke react-native

I have the following code (full example):
import React, { useState, useEffect } from 'react';
import { SafeAreaView, View, TextInput, Button, StyleSheet } from 'react-native';
const App = () => {
const [textblocks, setTextblocks] = useState([]);
const CreateTextBlockHandler = () => {
let array = [...textblocks];
array.push({text: ''});
setTextblocks(array);
};
const SaveTextHandler = (index, text) => {
let array = [...textblocks];
array[index].text = text;
setTextblocks(array);
};
const RenderTextInputs = () => {
return textblocks.map((item, index) => {
return (
<View key={index}>
<TextInput style={styles.textinput} placeholder="text" value={textblocks[index].text} onChangeText={value => SaveTextHandler(index, value)} />
</View>
);
});
};
return (
<SafeAreaView style={styles.pancontainer}>
<RenderTextInputs />
<Button title="Create textblock" onPress={CreateTextBlockHandler} />
</SafeAreaView>
);
};
const styles = StyleSheet.create({
pancontainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
textinput: {
width: 200,
margin: 10,
borderWidth: 1,
borderColor: 'black'
}
});
export default App;
How it works: I have a button to dynamically add a new textinput. This works. The problem is, for every character I enter in a textput, the focus is lost after every character.
I created a snack, you can test it here: https://snack.expo.io/BJcHxluyI.
I THINK I need to save the reference to the textinput somewhere, and then give the focus back to the textinput after every keystroke, but I don't know how to do that.
Change
return (
<SafeAreaView style={styles.pancontainer}>
<RenderTextInputs />
<Button title="Create textblock" onPress={CreateTextBlockHandler} />
</SafeAreaView>
);
To
return (
<SafeAreaView style={styles.pancontainer}>
{RenderTextInputs()}
<Button title="Create textblock" onPress={CreateTextBlockHandler} />
</SafeAreaView>
);
Or put RenderTextInputs outside App and pass data via props. With first syntax react treats RenderTextInputs as a component and, as it is nested in App, mounts it again on each App render.

React Native OnPress issue i have been having

I am new to react native and have been doing this for a week or so. I just finished the tutorials for making an interactive buttons and work on it. But i am stuck on this. The app is really simple right now, just trying to make a form and add some trigger event using onPress on it.
Below is the portion of my code. I am simply lost for words why its not calling SubmitThisForm() on the onPress event.
Can you guys help me on this.
Thanks a lot.
import React, { Component } from 'react';
import {Container, Content, InputGroup,Button, View, Icon, Card,
CardItem, Text, Body} from 'native-base';
import {Input} from './common';
class LoginForm extends Component {
state = {email: '', password: ''};
SubmitThisForm() {
console.log("Can you see this");
}
render () {
return (
<Container>
<Content>
<Card style={styles.FormContainer}>
<CardItem>
<Body>
<InputGroup borderType="regular">
<Icon name="ios-mail-outline" style={{color:'#384850'}}/>
<Input
placeHolder="example#example.com"
value = {this.state.email}
onChangeText={email=>this.setState( { email })}
/>
</InputGroup>
<InputGroup borderType="regular">
<Icon name="lock" style={{color:'#384850'}}/>
<Input
secureTextEntry= {true}
placeHolder="password"
value = {this.state.password}
onChangeText={password=>this.setState( { password })}
/>
</InputGroup>
</Body>
</CardItem>
</Card>
<View style={styles.SignIn}>
<Button block warning onPress={ () => {this.SubmitThisForm()}}><Text>Sign In</Text></Button>
</View>
<View style={styles.SignUp}>
<Button block info><Text>Sign Up</Text></Button>
</View>
<View style={styles.SignIn}>
<Button block primary><Text>Forgot Password</Text></Button>
</View>
</Content>
</Container>
);
};
}
const styles = {
ErrorTextStyle: {
fontSize: 20,
alignSelf: 'center',
color: 'red'
},
FormContainer:{
marginTop:30,
shadowColor:'#000',
shadowOffset:{width:0,height:2},
shadowOpacity:0.1,
shadowRadius:2,
},
SignIn:{
marginTop:10,
flex:1,
alignSelf:'stretch',
},
SignUp:{
marginTop:40,
flex:1,
alignSelf:'stretch',
}
}
export default LoginForm
The include input component is like this:
import React from 'react';
import {Text, View, TextInput} from 'react-native';
const Input = ({ label,value,onChangeText,placeHolder,secureTextEntry }) => {
const {InputStyle,LabelStyle,ContainerStyle } = styles;
return (
<View style = {ContainerStyle}>
<TextInput
secureTextEntry = {secureTextEntry}
placeholder={placeHolder}
autoCorrect={false}
style = {InputStyle}
value={value}
onChangeText={onChangeText}
/>
</View>
);
};
const styles = {
InputStyle:{
color:'#000',
paddingRight:5,
paddingLeft:5,
fontSize:18,
lineHeight:30,
flex:2,
height:40
},
LabelStyle:{
fontSize:18,
paddingLeft:20,
flex:1,
},
ContainerStyle:{
height:40,
flex:1,
flexDirection:'row',
alignItems:'center'
}
}
export { Input };
You need to either use an Arrow function, or bind() SubmitThisForm to your Component.
You can either declare your method like:
SubmitThisForm = () => {
console.log('Can you see this?')
}
Or, you can bind() your function in the constructor by adding:
constructor() {
super()
this.SubmitThisForm = this.SubmitThisForm.bind(this)
}
If you do not bind this in your custom functions, this will equal undefined. When you use Arrow functions however, this is lexically scoped which means the context of this will be the enclosing context (LoginForm)