React-Native Button On Press doesn't work - javascript

I can't bind my onPress method to my JSX button.
I've tried already tons of different solutions but none of them worked.
onPress Method:
class ScreenEnterPlayerNames extends Component {
constructor(props) {
super(props);
}
static navigationOptions = {
title: 'Player Names',
};
onPressStartTheGame = () => {
console.log("Pushed button Start the Game!")
//dispatch({ type: ADD_PLAYER_NAME, playerNumber: 5, playerName: "Sandro" })
}
Button:
return (
<View style={styles.viewMain}>
<View style={styles.viewTxt}>
<Text style={styles.TxtHeading}>
Please enter the names in sequence.
</Text>
</View>
<ScrollView style={styles.viewTextBox}>
{textBoxes}
</ScrollView>
<View style={styles.viewButton}>
<Button
title='Start the Game!'
onPress={() => this.onPressStartTheGame}
/>
</View>
</View>
);
}
}
I've tried it with following approaches as well:
onPress={this.onPressStartTheGame}
onPress={this.onPressStartTheGame()}
onPress={this.onPressStartTheGame.bind(this)}
onPress={() => this.onPressStartTheGame.bind(this)}
And I tried to change the function to:
onPressStartTheGame() {...
So I am pretty sure there is something else wrong but I can't figure out what.
Thank you! :-)

Try this for your method
onPressStartTheGame(){
console.log("Pushed button Start the Game!")
//dispatch({ type: ADD_PLAYER_NAME, playerNumber: 5, playerName: "Sandro" })
}
and call it like
onPress={this.onPressStartTheGame.bind(this)}
here you can double check and try the behave in a sandbox.
https://facebook.github.io/react-native/docs/handling-touches.html

Related

Natigate to different screes within same page in React Native

I have made a main screen in which I have added three button in the header, on pressing I want to open three different screens respectively but its not working.
Here's what I've tried:
constructor(props) {
super(props);
this.state = {
initialstate: 0, //Setting initial state for screens
};
}
render(){
return(
<View style={styles.container}>
<TouchableOpacity onPress={() => this.setState({ initialstate: 0})}>
<Image source={require('../../assets/add.png')}
resizeMode="contain"/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({ cardstate: 1})}>
<Image source={require('../../assets/request.png')}
resizeMode="contain"/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({ cardstate: 2})}>
<Image source={require('../../assets/send.png')}
resizeMode="contain"/>
</TouchableOpacity>
{this.state.initialstate == 0 ? ( <RequestComp/> ) : ( <TopUpComp/> ) } //Over Here when I use the Third Screen like " : <SendComp/> " it gives me JXS error says "EXPECTED }"
</View>
The first problem is that you have an initialState state variable that is only updated by the first buttons and the other two are setting cardState so even if the ternary statement was formatted correctly it wouldn't have worked either way
But aside from this problem I don't recommend using a ternary for what you're trying to do, because the conditions become difficult to read.
There are multiple ways of doing this, but I like the approach of the accepted answer here React render various components based on three logic paths). The idea is to create an object that holds a mapping of strings to components. Then you can conditionally render an item based on the current key value.
Here's an example of how you could refactor your code to use this approach:
const tabComponents = {
request: <RequestComp />,
topUp: <TopUpComp />,
send: <SendComp />,
};
class CustomTabs extends React.Component {
constructor(props) {
super(props);
this.state = {
cardstate: 'request', // Setting initial state for screens
};
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => this.setState({ cardstate: 'request' })}>
// Button content...
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({ cardstate: 'topUp' })}>
// Button content...
</TouchableOpacity>
<TouchableOpacity
onPress={() => this.setState({ cardstate: 'send' })}>
// Button content...
</TouchableOpacity>
{tabComponents[this.state.cardstate]}
</View>
);
}
}

React Native How to hide and show exact one view with key value

I want to make hide and show each view which have {param.body} in the list when I onPress the each TouchableOpacity. But all of my list view is hiding and showing when I onPress only one. How can I make only one view hide and show?
I've got the key value in each View.
this is my code
const DOWN_ARROW = require('../assets/images/ic_arr_down.png');
const UP_ARROW = require('../assets/images/ic_arr_up.png');
export default class Schedule extends Component{
constructor(props){
super(props);
this.state = {showbody : true, activeImage : true}
}
toggleBody = () =>{
this.setState({showbody : !this.state.showbody, activeImage : !this.state.activeImage,})
}
data = {
contents: [
{
date: '4/3',
money: '$15000',
body: 'this is component 1',
},
{
date: '4/4',
money: '$200000',
body: 'this is component 2',
},
]
}
render() {
let arrowImage = this.state.activeImage ? DOWN_ARROW : UP_ARROW;
return(
<View style = {styles.container}>
<ScrollView style={{alignSelf: 'stretch'}}>
{
this.data.contents ? this.data.contents.map((param, i) => {
return(
<View>
<View style={styles.dropdown} key={i}>
<Text style={{fontSize: 16}}>{param.date}</Text>
<TouchableOpacity style={{backgroundColor: 'blue'}} onPress={this.toggleBody}>
<Image source={arrowImage}/>
</TouchableOpacity>
</View>
{this.state.showbody ? (<View><Text>{param.body}</Text></View>) : null}
</View>
);
})
: null
}
</ScrollView>
</View>
)
}
}
I expect when I press image on view which key is 1, the view right below that contains {param.body} do hide and show. but all of the view is hide and showing. :(
This is most common type of problem most beginners face while start to work in React/React Native.You got to do like this.
1.Maintain a variable activeItem in state which by the name is holding the current active item.
2.Update this variable onPress inside the loop like this.
updateActiveItem=itemIndex=>{
this.setState({activeItem:itemIndex})
}
....
....
render(){
return(
<View>
{
someArrayofItems.map((item,index)=>{
return(
<View>
<Touchable onPress={()=>this.updateActiveItem(index)}>
...
</Touchable>
{this.state.activeItem===index &&(SOME VIEW YOU WANT TO SHOW
CONDITIONALLY)}
</View>
)
})
}
</View>
)
}
Follow this steps:-
1. Take one variable temp which will be empty on first time
2. Now on click of tochableopacity store that particluar item key in variable.
3. The condition of show view will like this
this.state.temp == param.keyvalue ? "show your view" : null
So it will work easily.
I suggested to use flatlist instead of this.

Touchable Opacity onPress not able to call function - scoping issue?

I'm developing in React Native.
I have a FlatList that renders items. I have added TouchableOpacity and would like to call a function upon press of that item, but the function is not being called.
When I click on the item I get an error of cannot find variable: _onPress
I think it's an issue with scoping. Would someone be able to explain to me what is going wrong please?
I guess a secondary question is: will my _onPress console.log the item name by passing the prop in like I have?
export default class ModalScreen extends React.Component {
//..
_onPress = (item) => {
console.log('Clicked:' + item)
};
renderItem({ item }) {
return (
<TouchableOpacity onPress={() => this._onPress(item)}>
<View>
<Text>{item.name}</Text>
</View>
</TouchableOpacity>
)
}
render() {
return (
//..
<View style={{flex: 2, backgroundColor: '#FFF', flexDirection:'row'}} >
<FlatList
data={this.state.searchedItems}
renderItem={this.renderItem}
/>
</View>
//..
try to change this 'renderItem({ item }) {' with this 'renderItem = ({ item }) => {

How to move an Image on click in React Native

I've recently been learning React Native but haven't really found a way to manipulate the DOM.
I've been trying to make it so that if I click on the TouchableHighlight my Image moves down a couple of px, but I have not managed to get it to move yet and I honestly don't know how to go from here.
My onclick function works since it does return the log every time the button is clicked.
As of now I have this:
export default class MainBody extends Component {
onclick = () => {
console.log('On click works')
};
render() {
return (
<ScrollView showsHorizontalScrollIndicator={false} style={Style.horList} horizontal={true}>
<View >
{/*i need to move this Image down!*/}
<Image source={require("./img/example.png")}/>
<View>
<Text style={Style.peopleInvited}>This is text</Text>
</View>
{/*When clicked on this touchable highlight!*/}
<TouchableHighlight onPress={this.onclick}}>
<Image source={require('./img/moveImg.png')}/>
</TouchableHighlight>
</View>
</ScrollView>
}
If someone could help me get past this that would be greatly appreciated.
Thank you so much for your time!
There are many ways to do this, but perhaps the easiest way would be using states.
class MainBody extends Component {
constructor(props) {
super(props);
this.state = {
top: 0 // Initial value
};
}
onclick = () => {
console.log('On click works')
this.setState( { top: this.state.top + 5 }) // 5 is value of change.
};
render() {
return (
<ScrollView showsHorizontalScrollIndicator={false} horizontal={true}>
<View >
{/*i need to move this Image down!*/}
<Image style={{top: this.state.top}}source={require("./img/example.png")}/>
<View>
<Text>This is text</Text>
</View>
{/*When clicked on this touchable highlight!*/}
<TouchableHighlight onPress={this.onclick}>
<Image source={require("./img/moveImg.png")}/>
</TouchableHighlight>
</View>
</ScrollView>
);
}
}

React Nat Counter

When clicking on a button, I want a value to increment by one each time. I want to call a function incrementCounter() to handle the operation for me, rather than: onPress={() => this.setState({Count: ++this.state.Count})}
This is my code so far for the class:
class Main extends React.Component{
constructor(props){
super(props);
this.state = {
Count: 0,
}
}
incrementCounter(){
this.setState({
Count: this.state.Count + 1 //!!! Where error occurs
});
}
render() {
return(
<View style={styles.mainContainer}>
<Text style={styles.title}>{'Count: ' + this.state.Count} </Text>
<TouchableHighlight
style={styles.button}
onPress={this.incrementCounter}
underlayColor='white'>
<Text style={styles.buttonText}>+</Text>
</TouchableHighlight>
</View>
)
}
};
The code above results in an error - a red screen:
"undefined is not an object (evaluating 'this.state.Count')" with the error on the line of the incrementCounter() <- Where comments show error occurs.
Most of the examples that I can find online are not using the ES6 syntax, however I want to try and stick to this to keep it standard across my application. The future work will include having a decrementCounter() function that will do the opposite, however will not allow the counter to drop below zero.
I see you are using the es6 notation, try the following:
render() {
return(
<View style={styles.mainContainer}>
<Text style={styles.title}>{'Count: ' + this.state.Count} </Text>
<TouchableHighlight
style={styles.button}
onPress={this.incrementCounter.bind(this)}
underlayColor='white'>
<Text style={styles.buttonText}>+</Text>
</TouchableHighlight>
</View>
)
}
Notice the .bind(this) on the event, this is needed so that it acutally references the class itself not some global function.

Categories