Uncaught Error: undefined is not an object (evaluating '_this.setState') - react-native

After a lot of research, I'm getting this error every time I enter text into the message box.
I've removed a lot of code - so the issue is with the TextInput and var state{ ... }
I have no idea what to do
I plan on submitting the data to an SQLite database in the future, but for now, I'm just trying to capture the text input on the button press - I found a script online, but it doesn't work.
const JournalNewEntryScreen = ({navigation}) => {
const messageImage = require('./images/Imatter-icons-13.png');
const homeImage = require('./images/Imatter-icons-14.png');
const settingsImage = require('./images/Imatter-icons-11.png');
const journalHomeImage = require('./images/Imatter-icons-09.png');
const cancelAlert = () =>
Alert.alert(
"Are You Sure?",
"Any content will be deleted and cannot be recovered",
[
{
text: "Cancel",
style: "cancel"
},
{ text: "Yes, I'm Sure",
onPress: () => navigation.navigate("JournalHome") }
]
);
var state = {
message: '',
}
const getValues = () => {
console.log(this.state.message);
}
return (
<>
<StatusBar barStyle='dark-content' />
<SafeAreaView style={homePage.flexContainer}>
<View style={{ flex: 1 }}>
<ScrollView>
<View style={JournalNewEntryPage.container}>
<Image
source={require("./assets/images/cropped-img_1619-1-e1610564001477.png")}
resizeMode="contain"
style={JournalNewEntryPage.image}>
</Image>
<Text style={JournalNewEntryPage.myJournal}>New Journal Entry</Text>
<Text style={JournalNewEntryPage.descriptionText}>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s
</Text>
<Text style={JournalNewEntryPage.messageText}>
Type a message
</Text>
<TextInput
multiline
editable
numberOfLines={4}
style={JournalNewEntryPage.textBox}
onChangeText={(text) => this.setState({ message: text })}
/>
<Text style={JournalNewEntryPage.messageText}>
Attach a file:
</Text>
<Text style={JournalNewEntryPage.upload}>
+ Add a photo, audio or video file
</Text>
<TouchableOpacity onPress={() => this.getValues()}>
<Text style = {JournalNewEntryPage.journalButton}>
Save Entry
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={cancelAlert}>
<Text style = {JournalNewEntryPage.journalButton}>
Cancel
</Text>
</TouchableOpacity>
<View style = {custom.spacer10}></View>
</View>
</ScrollView>
</View>
{/* <Button title="Reload" onPress={() => navigation.navigate('Home')}/> */}
<View style={homePage.tabBarContainer}>
<View style={homePage.column}>
<TouchableOpacity onPress={hide ? dataButtonHandler : onPress1}>
<Text style={hide ? homePage.button : homePage.codeButton}>{hide ? "Data" : "XXXXXX"}</Text>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<Image style={homePage.navImage} source={homeImage}/>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={() => navigation.navigate('JournalHome')}>
<Image style={homePage.navImage} source={journalHomeImage}/>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={messagesButtonHandler}>
<Image style={homePage.navImage} source={messageImage}/>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={() => navigation.navigate('Settings')}>
<Image style={homePage.navImage} source={settingsImage}/>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={hide ? logButtonHandler : onPress3}>
<Text style={hide ? homePage.button : homePage.codeButton}>{hide ? "Logs" : "XXXXXX"}</Text>
</TouchableOpacity>
</View>
</View>
<View style={homePage.tabBarContainerText}>
<View style={homePage.column}>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<Text style={homePage.button}>Home</Text>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={() => navigation.navigate('JournalHome')}>
<Text style={homePage.button}>Journal</Text>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={messagesButtonHandler}>
<Text style={homePage.button}>Messages</Text>
</TouchableOpacity>
</View>
<View style={homePage.column}>
<TouchableOpacity onPress={() => navigation.navigate('Settings')}>
<Text style={homePage.button}>Settings</Text>
</TouchableOpacity>
</View>
<View style={homePage.column}>
</View>
</View>
</SafeAreaView>
</>
);
};
Image of error

You're using functional component not class-based, so this is not the way to go with declaring states and setState, this only works with class-based component.
So you need to check this doc out for handling states with React Hooks https://reactnative.dev/docs/state

Related

Remove keyboard toolbar in react native

I want to remove keyboard toolbar. You can see Image. please tell me how can i remove keyboard toolbar.
here is my code:
<View style={styles.mainContainer}>
<View style={styles.messagesContainer}>
<FlatList
inverted={true}
data={messages}
renderItem={({ item }) => {
const newDate = new Date(item.createdAt)
return (
<View style={item.user._id === 1 ? styles.messageTextContainer2 : styles.messageTextContainer}>
<Text style={item.user._id === 1 ? styles.messageText2 : styles.messageText}>{item.text}</Text>
<Text style={item.user._id === 1 ? styles.timeText2 : styles.timeText}>{newDate.toLocaleTimeString()}</Text>
</View>
)
}}
/>
</View>
<View style={styles.inputContainer}>
<TextInput
autoCorrect={false}
onChangeText={setText}
style={styles.input}
placeholder="Type a message..."
value={text}
/>
<TouchableOpacity style={styles.sendContainer}>
<Text onPress={() => onSend()} style={styles.sendText}>Send</Text>
</TouchableOpacity>
</View>
</View>

How to show selected value from modal on text component in react-native

How to set selected value from modal on text component in react-native.
I am using modal component from 'react-native'.
import { StyleSheet, View, Text, TouchableOpacity, Image,Modal,} from 'react-native'
<View style={styles.vwstyle}>
<Text style={styles.texthead}>You are Interested in</Text>
<View style={styles.vwside}>
<Modal
animationType="fade"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
}}>
<View style={styles.vwmodal}>
<TouchableOpacity style={styles.touchmodal}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text style={styles.txtmodal}>Man</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchmodal}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text style={styles.txtmodal}>Woman</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchmodal}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text style={styles.txtmodal}>Everyone</Text>
</TouchableOpacity>
</View>
</Modal>
<TouchableOpacity
style={{flexDirection:'row'}}
onPress={() => {this.setModalVisible(true);}}>
<Text style={styles.txtselected}>Woman</Text>
<Image
source={require('../Images/rightarrow.png')} style={{ height: 20, width: 20, marginTop: 8, marginRight: 5 }} />
</TouchableOpacity>
</View>
</View>
You can use state to hold the values being pressed. I am including a code snippet here for your reference.
constructor(props) {
super(props);
this.state = {
otherStateVariables..... ,
pressedOption: ""
}
}
render() {
<View style={styles.vwstyle}>
<Text style={styles.texthead}>You are Interested in</Text>
<View style={styles.vwside}>
<Modal
animationType="fade"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
}}>
<View style={styles.vwmodal}>
<TouchableOpacity style={styles.touchmodal}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
/* Add this line to set your state on onPress handler*/
this.setState({pressedOption:"Man"})
}}>
<Text style={styles.txtmodal}>Man</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchmodal}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
/* Add this line to set your state on onPress handler*/
this.setState({pressedOption:"Woman"})
}}>
<Text style={styles.txtmodal}>Woman</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchmodal}
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
/* Add this line to set your state on onPress handler*/
this.setState({pressedOption:"Everyone"})
}}>
<Text style={styles.txtmodal}>Everyone</Text>
</TouchableOpacity>
</View>
</Modal>
<TouchableOpacity
style={{flexDirection:'row'}}
onPress={() => {this.setModalVisible(true);}}>
<Text style={styles.txtselected}>Woman</Text>
<Image
source={require('../Images/rightarrow.png')} style={{ height: 20, width: 20, marginTop: 8, marginRight: 5 }} />
</TouchableOpacity>
</View>
</View>
}
After setting the state, you can use that state variable anywhere in your code by using
this.state.pressedOption

how to hide/show text input in flat list react native?

I am new in react native and I need to show and hide for text input on each comment reply option.How to unique each and every section so I can hide and show text input for each button click.
Here is my flat list:
<FlatList
data={item.comments}
keyExtractor={this._keyExtractor}
renderItem={this.renderRowItem}
extraData={this.state}
/>
Here is render row item:
renderRowItem = (itemData) => {
Moment.locale('en');
return (
<View style={styles.commentSection}>
<View style={{flexDirection:'row'}}>
<View style={{flex:1,flexDirection:'row'}}>
<Image style={{ height: 30,width: 30,borderRadius: 15, marginTop:8}}
source={{ uri: this.state.profile_image }} resizeMode='cover' />
<View style={{width:width,paddingHorizontal:10,paddingRight:10,borderBottomColor:'#D2D0D1',borderBottomWidth:1,paddingBottom:10}}>
<View style={{flexDirection:'row',paddingTop:5}}>
<Text style={{fontWeight:'600',fontSize:14}}>
{itemData.item.firstName} {itemData.item.surname}</Text>
<Text style={{color:'grey',fontWeight:'500',fontSize:12,paddingHorizontal:20}}>
{Moment(itemData.item.dateCreated).format('d MMM YYYY')}</Text>
</View>
<Text style={{fontWeight:'500',color:'grey',marginTop:5}}>
{itemData.item.comment}</Text>
<Text onPress={this.ShowHideTextComponentView} style={{width:width*0.8,color:"#F766FF",textAlign:'right',alignSelf:'stretch',fontSize:12,fontWeight:'600'}}>
Reply</Text>
<View>
<FlatList
data={itemData.item.replies}
keyExtractor={this._keyExtractor}
renderItem={this.renderRowReply}
/>
</View>
<View>
{
this.state.replyboxShow ?
<View style={{flex:1,flexDirection:'row',width:width*0.6,marginLeft:10}}>
<TextInput
style = {[styles.inputReplyBox,
!this.state.postValidate ? styles.error : null]}
placeholder="Enter message here"
placeholderTextColor="grey"
onChangeText = {reply => this.setState({reply})}
/>
<TouchableOpacity style={{position: 'absolute',right:6,top:5,alignSelf:'stretch'}}
onPress={() => this.replyCom(itemData.item._id)}>
<Icon name="paper-plane-o" size={20} color="#F766FF" />
</TouchableOpacity>
</View>
: null
}
</View>
</View>
</View>
</View>
</View>
)
}
In the end of render item I am using reply button and on click I want to show and hide each text input fields:
This is design I need to implement.
My ShowHideTextComponentView function:
ShowHideTextComponentView = () =>{
if(this.state.replyboxShow == true){
this.setState({replyboxShow: false})
}else{
this.setState({replyboxShow: true})
}
}
With your replyboxShow state, all the item will be showing or hiding,
i create a replyboxShowId state to save the item_id of the element
you want to show.
renderRowItem = (itemData) => {
Moment.locale('en');
return (
<View style={styles.commentSection}>
<View style={{flexDirection:'row'}}>
<View style={{flex:1,flexDirection:'row'}}>
<Image style={{ height: 30,width: 30,borderRadius: 15, marginTop:8}}
source={{ uri: this.state.profile_image }} resizeMode='cover' />
<View style={{width:width,paddingHorizontal:10,paddingRight:10,borderBottomColor:'#D2D0D1',borderBottomWidth:1,paddingBottom:10}}>
<View style={{flexDirection:'row',paddingTop:5}}>
<Text style={{fontWeight:'600',fontSize:14}}>
{itemData.item.firstName} {itemData.item.surname}</Text>
<Text style={{color:'grey',fontWeight:'500',fontSize:12,paddingHorizontal:20}}>
{Moment(itemData.item.dateCreated).format('d MMM YYYY')}</Text>
</View>
<Text style={{fontWeight:'500',color:'grey',marginTop:5}}>
{itemData.item.comment}</Text>
<Text onPress={this.ShowHideTextComponentView.bind(this,itemData.item._id)} style={{width:width*0.8,color:"#F766FF",textAlign:'right',alignSelf:'stretch',fontSize:12,fontWeight:'600'}}>
Reply</Text>
<View>
<FlatList
data={itemData.item.replies}
keyExtractor={this._keyExtractor}
renderItem={this.renderRowReply}
/>
</View>
<View>
{
this.state.replyBoxShowId === itemData.item._id ?
<View style={{flex:1,flexDirection:'row',width:width*0.6,marginLeft:10}}>
<TextInput
style = {[styles.inputReplyBox,
!this.state.postValidate ? styles.error : null]}
placeholder="Enter message here"
placeholderTextColor="grey"
onChangeText = {reply => this.setState({reply})}
/>
<TouchableOpacity style={{position: 'absolute',right:6,top:5,alignSelf:'stretch'}}
onPress={() => this.replyCom(itemData.item._id)}>
<Icon name="paper-plane-o" size={20} color="#F766FF" />
</TouchableOpacity>
</View>
: null
}
</View>
</View>
</View>
</View>
</View>
)
}
ShowHideTextComponentView:
ShowHideTextComponentView = (id) =>{
this.setState({
replyBoxShowId : id
})
}

react-native-swipeout onPress method disables containing component's onPress method

I have the following flatlist render method that upon tapping on a list item, it will call the this._onPress method:
render() {
return (
<TouchableOpacity onPress={this._onPress} >
<View style={styles.bookItem} >
<Image style={styles.cover} source={{uri:this.props.coverURL}}/>
<View style={styles.info} >
<Text style={styles.title}>{this.props.title} </Text>
<Text style={styles.author}>{this.props.author}</Text>
<Text style={{height: 8}}/>
</View>
<View style={styles.rightIcon}>
<Icon name="chevron-right" size={28} color={'#AAAAAA'} />
</View>
</View>
</TouchableOpacity>
);
}
After I added the swipeout tag in the following code, the swipeout works but tapping on an item no longer calls the this._onPress method:
render() {
// Buttons
var swipeoutBtns = [
{
text: 'Delete',
onPress: this._buttonPress
}
]
return (
<TouchableOpacity onPress={this._onPress} >
<Swipeout right={swipeoutBtns} >
<View style={styles.bookItem} >
<Image style={styles.cover} source={{uri:this.props.coverURL}}/>
<View style={styles.info} >
<Text style={styles.title}>{this.props.title} </Text>
<Text style={styles.author}>{this.props.author}</Text>
<Text style={{height: 8}}/>
</View>
<View style={styles.rightIcon}>
<Icon name="chevron-right" size={28} color={'#AAAAAA'} />
</View>
</View>
</Swipeout>
</TouchableOpacity>
);
}
Is this a restriction of react-native-swipeout?
If you were to have Swipeout as the first tag and touchable as the next nested tag I think it would work. However, its seems to make the Swipeout functionality less responsive

onPress not working in nested views

I'm using TouchableOpacity for handling clicks.Everything is working fine in upper hierarchy views, but bellow two containers view is not clickable.I've set an alert when it's clicked for testing purposes.View bellow comment is not working and I think it's because of bad nesting.
Here is code :
return (
<View style={styles.container}>
<View style={styles.subContainer}>
<Text style={[styles.storyLikesAndShares, { marginRight: 17 }]}>
{this.state.likes} Likes
</Text>
<Text style={styles.storyLikesAndShares}>
{this.props.story.Shares ? this.props.story.Shares : 0} Shares
</Text>
</View>
<View style={[styles.subContainer, { paddingTop: 16 }]}>
<View style={styles.storyIconsContainer}>
<TouchableOpacity onPress={() => this.changeLikedState(this.props)}>
<Icon
style={[
this.props.story && this.state.isLiked
? styles.storyLikedIcon
: styles.storyNotLikedIcon,
{ marginRight: 24 }
]}
name={"heart"}
size={24}
/>
</TouchableOpacity>
<Icon style={styles.storyNotLikedIcon} name={"share"} size={24} />
//Code bellow is not working
<TouchableOpacity
onPress={() => alert('alertiiiing')}
>
{this.props.storyViewType === "feed" ? (
<Text
onPress={() => console.log('read more clicked')}
style={styles.storyReadMoreText}>Read Full Story...</Text>
) : (
<View />
)}
</TouchableOpacity>
</View>
</View>
</View>
);
}
}