How to change text Value upon Button press in React Native? - javascript

I'm an iOS developer currently working on an experimental React Native app.
I have the following code which shows a button and sample text on the screen.
import React from 'react';
import { StyleSheet, Text, View , Button } from 'react-native';
export default class App extends React.Component {
constructor() {
super();
this.state = {sampleText: 'Initial Text'};
}
changeTextValue = () => {
this.setState({sampleText: 'Changed Text'});
}
_onPressButton() {
<Text onPress = {this.changeTextValue}>
{this.state.sampleText}
</Text>
}
render() {
return (
<View style={styles.container}>
<Text onPress = {this.changeTextValue}>
{this.state.sampleText}
</Text>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Change Text!"
color="#00ced1"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5deb3',
alignItems: 'center',
justifyContent: 'center',
},
buttonContainer: {}
});
The above code displays text and a button.
However when I click the button, the app crashes instead of showing the new text which is to be shown.
I'm new to React Native, kindly guide me on how to solve the error.

You could use a state to keep your default text and then on press we update the state.
import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
export default class App extends Component {
state = {
textValue: 'Change me'
}
onPress = () => {
this.setState({
textValue: 'THE NEW TEXT GOES HERE'
})
}
render() {
return (
<View style={{paddingTop: 25}}>
<Text>{this.state.textValue}</Text>
<Button title="Change Text" onPress={this.onPress} />
</View>
)
}
}

You can use state for dynamically change the text
import React, {Component} from 'react';
import {Text, Button, View} from 'react-native';
export default class App extends Component{
constructor(){
super();
this.state = {
textValue: 'Temporary text'
}
this.onPressButton= this.onPressButton.bind(this);
}
onPressButton() {
this.setState({
textValue: 'Text has been changed'
})
}
render(){
return(
<View style={{paddingTop: 20}}>
<Text style={{color: 'red',fontSize:20}}> {this.state.textValue} </Text>
<Button title= 'Change Text' onPress= {this.onPressButton}/>
</View>
);
}
}

With hooks:
import React, {useState} from "react";
import {Button, Text, View} from "react-native";
const App = () => {
const [text, setText] = useState("Initial text");
const onPressHandler = event => setText("Changed text");
return (
<View>
<Text>{text}</Text>
<Button title="Change Text" onPress={onPressHandler} />
</View>
);
};

You better make sure what _onPressButton() is doing. You can simply setState() in this function and do nothing else, which can help you solve the problem. If you want to render something new, you have to add return() and wrap up Text.

You can use this approach for updating a value on click of a button
class App extends React.Component {
constructor() {
super();
this.state = { val: 0 }
this.update = this.update.bind(this)
}
update() {
this.setState({ val: this.state.val + 1 })
}
render() {
console.log('render');
return <button onClick={this.update}>{this.state.val}</button>
}
}

It's because your onPress function is a little weird, you want to invoke an action on press, not have jsx elements. Your changeTextValue is what should be passed into your button's onPress.

Set my text in state method then update state in pressed button, then set in text like this:
<Text>
{this.state.myText}
</Text>

import React, { useState } from "react";
import { View, Text } from "react-native";
const App = () => {
const [value, setValue] = useState("Mohd Sher Khan");
const hellod = () => {
setValue("value changed");
};
return (
<View>
<Text onPress={hellod}>{value}</Text>
</View>
);
};
export default App;

Related

How to use onChange in custom textinput react native

So im new at react native and i built an custom text input that gives suggestions by following a tutorial.But now i cant use onChange in that custom text input.I tried to create a state in App.js and change it in AutoCompleteText.js file but didnt worked.How can i get the value inmy custom text input ?
my App.js file :
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AutoCompleteText from './AutoCompleText'
import './AutoCompleteText.css';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.AutoComp}>
<AutoCompleteText items={['Ali','Veli','Ahmet']} />
</View>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
AutoComp:{
width:600
}
});
my AutoCompleteText.js file
import React from 'react'
import './AutoCompleteText.css';
export default class AutoCompleteText extends React.Component{
constructor(props){
super(props);
this.state={
suggestions:[],
text:'',
};
}
onTextChanged = (e) =>{
const {items} = this.props;
const value = e.target.value;
let suggestions = [];
if (value.length > 0){
const regex = new RegExp(`^${value}`,'i');
suggestions = items.sort().filter(v => regex.test(v));
}
this.setState(() => ({ suggestions , text: value }));
}
suggestionSelected(value){
this.setState(() =>({
text: value,
suggestions:[],
}) )
}
renderSuggestions(){
const {suggestions} = this.state;
if (suggestions.length === 0){
return null;
}
return(
<ul>
{suggestions.map((item) => <li onClick={() => this.suggestionSelected(item)}>{item}</li>)}
</ul>
);
}
render(){
const { text } = this.state;
return(
<div className="AutoCompleteText">
<input value={text} onChange={this.onTextChanged} type ='text'/>
{this.renderSuggestions()}
</div>
)
}
}
hi Ülkü Tuncer Küçüktaş,
You are writing the wrong syntax. You are mixing the syntax of react native with react. In react native for textinput, you should use the TextInput Component(Built in component from docs).
The syntax of react native TextInput look like below
import React from 'react';
import { TextInput } from 'react-native';
const UselessTextInput = () => {
const [value, onChangeText] = React.useState('Useless Placeholder');
return (
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onChangeText={text => onChangeText(text)}
value={value}
/>
);
}
export default UselessTextInput;

How to use TextInput isFocused() Method

According to this link in the React Native API Documents:
https://facebook.github.io/react-native/docs/0.59/textinput#isfocused
The TextInput component has a method called isFocused(). How would I go about accessing this method? Do I have to use a ref?
Also, I already know that I can achieve the same effect by using the onFocus prop and setting up a state manager and a function to change the state of the input based on the onFocus. However, I am just curious how I would go about using these component methods since there are others in other components as well.
I have tried using this
<TextInput onChangeText={this.handleText} style={(this.isFocused()) ? styles.input : styles.lame} placeholder="Names"/>
but it is looking like I might have to use a ref since it seems that it isn't defined even though the method should be a part of this component.
isFocused() should be called on ref to TextInput.
import React, {useEffect, useRef} from 'react';
import {TextInput, BackHandler} from 'react-native';
function SearchBar() {
const textInputReference = useRef(null);
useEffect(() => {
let backhandler = BackHandler.addEventListener(
'hardwareBackPress',
function() {
if (textInputReference.current.isFocused()) {
textInputReference.current.blur();
return true;
}
return false;
},
);
return () => {
backhandler.remove();
};
}, []);
return (
<TextInput ref={textInputReference} />
);
}
export default SearchBar;
You can use state for handle input focus, if you have multi-input that also need focus state, just create many state for it.
class MyComponent extends React.Component {
state = { isFocused: false }
handleInputFocus = () => this.setState({ isFocused: true })
handleInputBlur = () => this.setState({ isFocused: false })
render() {
const { isFocused } = this.state
return (
<View>
<TextInput
onFocus={this.handleInputFocus}
onBlur={this.handleInputBlur}
style={ isFocused ? styles.input : styles.lame}
/>
<Text>Hello World</Text>
</View>
)
}
}
This another easy way to use the onFocus prop in TextInput
import React, { useState } from 'react'
import { View, StyleSheet, TextInput } from 'react-native'
const TextInput = () => {
const [isHighlighted, setIsHighlighted] = useState(false)
return (
<View>
<TextInput
style={[styles.textInput, isHighlighted && styles.isHighlighted]}
onFocus={() => { setIsHighlighted(true)}
onBlur={() => {setIsHighlighted(false)} />
</View>
)
}
const styles = StyleSheet.create({
textInput: {
borderColor: 'grey',
borderWidth: StyleSheet.hairlineWidth,
borderRadius: 8,
height: 43,
},
isHighlighted: {
borderColor: 'green',
}
})
According to its documentation
Returns true if the input is currently focused; false otherwise.
How we can achieve that? the answer is useRef.
For example :
import React, { useRef } from 'react'
import { View, StyleSheet, TextInput, Button } from 'react-native'
const App = props => {
const inputRef = useRef(null);
const checkIsFocusedHandler = () => {
const result = inputRef.current.isFocused();
alert(result);
}
return (
<View style={styles.container}>
<TextInput ref={inputRef} style={styles.input} value="Abolfazl Roshanzamir" />
<TextInput style={styles.input} />
<Button title="Check isFocused" onPress={checkIsFocusedHandler} />
</View>
)
}
If we click on the first TextInput then click on the button, the result is => true,
if we click on the second TextInput then click on the button, the result is => false.
Use onFocus props of TextInput component
<TextInput onFocus={yourCallBack} />
yourCallBack function will be called when the TextInput is focused

How to call function from different component bound to flatlist in React Native

I am creating a chat application in React Native that receives different "message types" as a response. One of them contains an array of buttons that I am currently rendering in a Flatlist in Component "ChatQuickReply" that looks like this:
import React from "react";
import {
StyleSheet,
FlatList,
View,
TouchableOpacity,
Text
} from "react-native";
class ChatQuickReply extends React.Component {
constructor(props) {
super(props);
}
renderItem({ item }) {
return (
<TouchableOpacity onPress={this._onPressQuickReply}>
<View style={styles.quickButton}>
<Text style={styles.quickButtonText}>{item.title}</Text>
</View>
</TouchableOpacity>
);
}
_onPressQuickReply = () => {
alert(Hello);
};
render() {
return (
<View>
<FlatList
data={this.props.buttons}
keyExtractor={(item, index) => "key" + index}
renderItem={this.renderItem}
/>
</View>
);
}
}
I am rendering this component in a different component also in a Flatlist which works fine.
The problem is, that I am not able to call the function that I am assigning to my TouchableOpacity. How can I call this function from a different component?
I think, what you can try to trigger onPress event for your TouchableOpacity component.
You need ref for this.
ref={touchableOpacity => this._touchableOpacity = touchableOpacity}
then when you want to launch onPress without clicking it just call
this._touchableOpacity.touchableHandlePress();
Depending on the relationship between both components, if the ChatQuickReply reply is a parent component, you can pass the function in the child as props and call it.
import React from "react";
class ChatQuickReply extends React.Component {
renderItem({ item }) {
return (
<TouchableOpacity onPress={this._onPressQuickReply}>
<View style={styles.quickButton}>
<Text style={styles.quickButtonText}>{item.title}</Text>
</View>
</TouchableOpacity>
);
}
_onPressQuickReply = () => {
alert(Hello);
};
render() {
return (
<View>
<FlatList
data={this.props.buttons}
keyExtractor={(item, index) => "key" + index}
renderItem={this.renderItem}
/>
**<ChildComponent clickParentFunction={this._onPressQuickReply} />**
</View>
);
}
}
class ChildComponent extends React.Component {
onClick = () => {
const {clickParentFunction} = this.props
clickParentFunction() // We can call it here
}
// We create a trigger to the onclick
}
or you can take the _onPressQuicklyReply function to the component that renders both components and pass it in to make it more generic
import OtherComponent from './Othercomponent';
class ParentComponent {
_onPressQuickReply = () => {
alert(Hello);
}
return (
<View>
<ChatQuicklyReply onParentFunction={this._onPressQuickly}>
<OtherComponent onParentFunctionCall={this._onPressQuickly} />
</View>
)
}

onSubmitEditing never fires?

Really simple question, why isn't onSubmitEditing firing when I hit 'Search' on the virtual keyboard?
Currently there are no errors thrown and the console.log in onSearch() never fires.
I'm using the EXPO SDK v.29.
import React from 'react';
import { StyleSheet, Text, View, TextInput, ScrollView, Image } from 'react-native';
import { WebBrowser } from 'expo';
import Icon from 'react-native-vector-icons/Ionicons';
import Styles from 'app/constants/Styles';
import Vars from 'app/constants/Vars';
import Menu from 'app/components/Menu';
import MiniMap from 'app/components/MiniMap';
import NewsList from 'app/components/NewsList';
import {get, post} from 'app/helpers/api';
export default class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: (<Image style={{width: 132, height: 30}} source={require('./../../assets/images/header_image.png')}/>)
};
};
constructor(props) {
super(props);
this.state = {
menu: [],
loadingMenu: true,
searchString: '',
};
}
onMenuPress = (item) => {
let next;
let route = item.page_type.slice(4);
if(route == "PageExternal") {
WebBrowser.openBrowserAsync(item.page.url);
} else {
data = item.page;
if(item.children.length > 0) {
route = 'Menu';
data = item.children;
}
this.props.navigation.navigate(route, {
data: data,
title: item.title
});
}
}
onSearch = (e) => {
console.log('onSearch', e);
//WebBrowser.openBrowserAsync('https://www.1177.se/Halland/Sok/?q=Diabetes&submitted=true');
}
async componentDidMount() {
console.log('Eat my shorrs');
menuitems = await get('content/menu');
this.setState({
menu: menuitems,
loadingMenu: false,
})
//this._getMenu();
}
render() {
return (
<ScrollView style={Styles.whiteBackground}>
<View style={[Styles.blueBackground, Styles.topPadding, Styles.horizontalPadding]}>
<View style={[Styles.searchBox, Styles.bottomMargin]}>
<View style={Styles.searchField}>
<TextInput
style = {Styles.searchInput}
placeholder = "Sök sjukdom/behandling"
onSubmitEditing = {(e) => (this.onSearch(e))}
underlineColorAndroid = "transparent"
returnKeyLabel = "Sök på 1177"
returnKeyType = "search"
/>
<Icon style = {Styles.searchIcon} name = "ios-search" size={18}/>
</View>
<Text style={[Styles.searchLabel]}>Söksvaren kommer från 1177.se</Text>
</View>
<Menu
data={this.state.menu}
loading={this.state.loadingMenu}
style={Styles.topPadding}
onItemPress={this.onMenuPress}
/>
</View>
<Text style={[Styles.h1, Styles.blackText, Styles.horizontalPadding]}>Hitta till oss</Text>
<MiniMap navigation={this.props.navigation}></MiniMap>
<Text style={[Styles.h1, Styles.blackText, Styles.horizontalPadding]}>Nyheter</Text>
<NewsList navigation={this.props.navigation}></NewsList>
</ScrollView>
);
}
}
<TextInput
onSubmitEditing = {(event) => (this.onSearch(event.nativeEvent.text))}
multiline={false}
/>
It does not work when multiline={true} is specified, perhaps your styles has that. See Documentation
You will find your text with event.nativeEvent.text
Try changing
onSubmitEditing = {(e) => (this.onSearch(e))}
to
onSubmitEditing = {this.onSearch}
Then keep
onSubmitEditing = {(e) => this.onSearch(e)}
like this and try by changing the function like below
function onSearch(e) {
console.log('onSearch', e);
//WebBrowser.openBrowserAsync('https://www.1177.se/Halland/Sok/?q=Diabetes&submitted=true');
}
Hope this will work
Check this out
https://snack.expo.io/#raajnadar/submit-text-input
Render method
render() {
return (
<View style={styles.container}>
<TextInput
placeholder="Sök sjukdom/behandling"
onSubmitEditing={this.onSearch}
underlineColorAndroid="transparent"
returnKeyLabel="Sök på 1177"
returnKeyType="search"
style={{ width: '100%', textAlign: 'center' }}
/>
</View>
);
}
On submit function
onSearch() {
console.log('onSearch')
}

Displaying props in a second target box

I'm very new to react-native. I'm currently experimenting with it to figure out how I can use it in different ways. Presently, I'm trying to call props of a specifically tapped object and send them to an output box.
So when you tap 'Alan' or 'Steve' their name will appear in the red box.
I'd also like for the dark blue backkground to change to dark red once it's tapped?
I have had a good read of the docs, but I reckon I'm not getting it because it's new to me. I know that I don't seem to be able to access the props of Component which is obviously the class Obj extends
Guidance greatly appreciated.
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import style from './style';
class Obj extends Component {
render(){
return(
<TouchableOpacity
onPressIn={() => this.setState({tapped: true, tappedName: this.props.plrName})}
onPressOut={() => this.setState({tapped: false, tappedName: null})}>
<View style={[style.playerobject, style.shadow]}>
<Text style={[style.plrobjText]}>{this.props.plrName}</Text>
</View>
</TouchableOpacity>
)
}
}
export default class App extends Component {
constructor(props){
super(props);
this.state = {
tapped: false,
tappedName: null,
};
}
render() {
return (
<View style={[style.main]}>
<View style={[style.container, this.state.tapped ? {backgroundColor:'darkred'} : {backgroundColor:'darkblue'} ]}>
<Obj plrName='Alan' />
<Obj plrName='Steve' />
</View>
<View style={style.box }><Text>|{this.state.tapped ? this.state.tappedName : 'x'}|</Text></View>
</View>
);
}
}
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import style from './style';
class Obj extends Component {
onPressIn = () => {
this.props.onPressIn(this.props.plrName)
}
onPressOut = () => {
this.props.onPressOut()
}
render() {
return (
<TouchableOpacity
onPressIn={this.onPressIn}
onPressOut={this.onPressOut}>
<View style={[style.playerobject, style.shadow]}>
<Text style={[style.plrobjText]}>{this.props.plrName}</Text>
</View>
</TouchableOpacity>
)
}
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
tapped: false,
tappedName: null,
};
}
onPressIn = (tappedName) => {
this.setState({ tapped: true, tappedName })
}
onPressOut = () => {
this.setState({ tapped: false, tappedName: null })
}
render() {
return (
<View style={[style.main]}>
<View style={[style.container, this.state.tapped ? { backgroundColor: 'darkred' } : { backgroundColor: 'darkblue' }]}>
<Obj plrName='Alan' onPressIn={this.onPressIn} onPressOut={this.onPressOut} />
<Obj plrName='Steve' onPressIn={this.onPressIn} onPressOut={this.onPressOut} />
</View>
<View style={style.box}><Text>|{this.state.tapped ? this.state.tappedName : 'x'}|</Text></View>
</View>
);
}
}

Categories

Resources