I am trying to launch a custom Alert component from an onPress call from Touchable Highlight. I have been unable to get this to work, I have tried console logging from inside the custom Alert component render function and the code doesn't run to this point because I am unable to see this log. What is confusing me is that when I tested this with the React-Native Alert this did run and show that Alert. I would appreciate some help understanding what I am doing wrong here because I feel I am misunderstanding something. I have used the Alert component before and it works fine but in these instances it has only been when i have called the Alert directly not from onPress.
onPress() {
return (
<Alert
message={i18n('alerts.improvements')}
/>
)
}
render() {
return (
<TouchableHighlight onPress={() => this.onPress.bind(this)}>
<Text>Test Text</Text>
</TouchableHighlight>
)
}
The Alert Component with the console log that doesn't get hit:
class Alert extends Component{
props: {
message: string
}
state = {
modalVisible: false,
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
console.log('modal')
return (
<Modal
animationStyle='fade'
transparent={true}
visible={!this.state.modalVisible}
onRequestClose={() => {}}
>
<View style={styles.container}>
<Text style={styles.text}>{this.props.message}</Text>
</View>
</Modal>
)
}
}
export default Alert
Rather than calling it onPress you can have default visible false and place it in render. Then add one more prop to your component which will manage visibility of it.
for example:
in component:
<Modal
animationType={'fade'}
transparent={true}
visible={this.props.isOpen}
onRequestClose={this.props.actionClose}>
while calling:
<ModalBox
isOpen={this.props.isOpen}
I have isOpen prop for visibility
Related
code:
export default class app extends Component {
state={
name:''
}
render(){
return(
<View>
<TextInput onChangeText={this.handle}></TextInput>
<TouchableOpacity
onPress={this.handleSubmit(this.state.name)}>
<Text>go</Text>
</TouchableOpacity>
</View>
)
}
handle=(text)=>{
this.setState({name:text})
}
handleSubmit=(name)=>{
alert(name)
}
}
every time I enter text,The handleSubmit function will use,why?
<TouchableOpacity
onPress={()=>this.handleSubmit(this.state.name)}>
<Text>go</Text>
</TouchableOpacity>
If i write like this,The problem is solved,but why?
The handleSubmit function invoked automatically every time when the render cycle occurs the component so when the text changes occur and that's why the function automatically invokes so you have to put the arrow function to must call when they go button press event occurs.
as you are using () here in the this.handleSubmit(this.state.name).
The question is almost similar to this one :
touchableopacity onpress function undefined (is not a function) React Native
But the problem is, I am getting the error despite the fact that I have bind the function. Here is my TouchableOpacity component:
<TouchableOpacity style={styles.eachChannelViewStyle} onPress={() => this.setModalVisible(true)}>
{item.item.thumbnail ?
<Image style={styles.everyVideoChannelThumbnailStyle} source={{uri: item.item.thumbnail}} />
: <ActivityIndicator style= {styles.loadingButton} size="large" color="#0000ff" />}
<Text numberOfLines={2} style={styles.everyVideoChannelVideoNameStyle}>
{item.item.title}
</Text>
</TouchableOpacity>
And this is my setModalVisible function:
setModalVisible(visible) {
console.error(" I am in set modal section ")
this.setState({youtubeModalVisible: visible});
}
Also, I have bind the function in constructor as follows:
this.setModalVisible = this.setModalVisible.bind(this);
But, I am still getting same error that undefined is not a function. Any help regarding this error?
The render method and your custom method must be under the same scope. In code below I have demonstrated the same. I hope you will modify your code accordingly as I assume you got the gist :)
class Demo extends Component {
onButtonPress() {
console.log("click");
}
render() {
return (
<View>
<TouchableOpacity onPress={this.onButtonPress.bind(this)}>
<Text> Click Me </Text>
</TouchableOpacity >
<View>
);
}
}
Alternatively binding method in constructor will also work
class Demo extends Component {
constructor(props){
super(props);
this.onButtonPress= this.onButtonPress.bind(this);
}
onButtonPress() {
console.log("click");
}
render() {
return (
<View>
<TouchableOpacity onPress={this.onButtonPress()}>
<Text> Click Me </Text>
</TouchableOpacity >
<View>
);
}
}
I'm not sure if this will help but I write my functions this way and haven't encountered this problem.
If I were you I'd try binding the function in the place where you declare it.
setModalVisible = (visible) => {
this.setState({ youtubeModalVisible: visible });
}
If you do this, you don't have to bind in the constructor.
constructor(props) {
...
// Comment this out to see it will still bind.
// this.setModalVisible = this.setModalVisible.bind(this);
...
}
Lastly, if this function will only set the modal's state to visible, you might want to remove the argument and pass it this way.
<TouchableOpacity style={styles.eachChannelViewStyle} onPress={this.setModalVisible}>
...
</TouchableOpacity>
// Refactored function declaration would look like this
setModalVisible = () => {
this.setState({ youtubeModalVisible: true });
}
I used the 'StackNavigator', I have issue to push when navigation code write in button event. but its working fine if we directly code onPress event,
Import file.
import { StackNavigator } from "react-navigation";
import SignUpScreen from "./SignUp";
Push another is working :
render() {
console.disableYellowBox = true;
const { navigate } = this.props.navigation;
return (
<View style={styles.viewStyle}>
<TouchableHighlight style = {styles.buttonStart}
onPress={() => navigate("SignUpCompany")}>
<Image
source={require('./Images/hire.png')}
/>
</TouchableHighlight>
</View>
);
}
Push another via function is not working :
pushcode() {
console.log('call');
this.props.navigation.navigate('SignUp');
}
render() {
return (
<TouchableHighlight style = {styles.buttonStart}
onPress={this.pushcode}>
<Image
source={require('./Images/hire.png')}
/>
</TouchableHighlight>
);}
ERROR ON CLICK BUTTON :
Thanks. Please help me.
Look like you are using the push extra in this line
this.props.navigation.navigate.push('SignUp');
Try this will work for you
this.props.navigation.navigate('SignUp');
May be this can help you
I think you miss the function bind within constructor --- that's why you got undefined is not an object (evaluating 'this.props.navigation'). because this is undefined inside pushcode function scope.
add below into your constructor:
constructor(props) {
super(props);
this.pushcode = this.pushcode.bind(this);
...
}
I am working on a simple calculator app to learn react native. I have a button component that displays the number buttons. I need to pass it a function so that when the button is touched the state of the parent is updated to the new number.
Without the bind(this) it says this.setState is undefined. When I add bind(this) in the constructor all I get is a blank page in my app. My code is listed below.
constructor:
constructor() {
super();
this.state = {
total: 0,
display: 0
};
this._displayUpdate = this._displayUpdate.bind(this);
}
One row of calculator buttons:
<View style={styles.buttonRow}>
<NumButton numText={7} update={this._displayUpdate} />
<NumButton numText={8} update={this._displayUpdate} />
<NumButton numText={9} update={this._displayUpdate} />
<FuncButton funcText={'*'} />
</View>
NumButton Component:
export default class NumButton extends Component {
render() {
return (
<TouchableHighlight style={styles.buttonArea} onPress={this.props.update(this.props.numText)}>
<Text style={styles.buttonText}>{this.props.numText}</Text>
</TouchableHighlight>
)
}
}
Your parent bind is right. The problem is with the onPress of the TouchableHighlight in the NumButton component. You can't add code to execute to it, You should pass a function to it. You can use ES6 arrow function:
export default class NumButton extends Component {
render() {
return (
<TouchableHighlight style={styles.buttonArea}
onPress={()=>{ this.props.update(this.props.numText) }}
>
<Text style={styles.buttonText}>{this.props.numText}</Text>
</TouchableHighlight>
)
}
}
I'm new to React Native and trying ( followed a tutorial ) to move to another screen when a button is clicked, this is the updated code I have and a photo of the error I get when pressing the button.
index.ios.js:
export default class Application extends Component {
constructor(){
super();
}
renderScene(route, navigator){
if(route.name == 'login'){
return <Login navigator={navigator}/>
}else if(route.name == 'home'){
return <Home navigator={navigator}/>
}
}
render() {
return <Navigator
initialRoute={{name: 'login'}}
renderScene={this.renderScene.bind(this)}/>
}
}
LoginForm:
export default class LoginForm extends Component{
constructor(props){
super(props);
this.navigate = this.navigate.bind(this);
}
navigate(routeName){
this.props.navigator.replace({
name: routeName,
Component: Home
});
}
render(){
return(
<View style={mStyle.container}>
<StatusBar barStyle='light-content'/>
<TouchableOpacity>
<Text style={mStyle.btnText}>
LOGIN WITH FACEBOOK
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this.navigate('home')}>
<Text style={mStyle.noLoginTxt}>
CONTINUE WITHOUT LOGIN
</Text>
</TouchableOpacity>
</View>
);
}
}
I'm trying to move from login screen to home screen when button is clicked.
I get this problem when pressing the button on the emulator:
A couple of problems that you are facing.
1.- The syntax is:
this.props.navigator.{any_method}
Such as:
this.props.navigator.push
this.props.navigator.replace
Not
this.props._navigate.{any_method}
2.- If you have child views make sure you are sending to the childs the Navigator property such as.
<View>
<MyChildComponent navigator={this.props.navigator} />
</View>
3.- Make sure your child view gets the props from the parent on the constructor.
Change
constructor(){
super();
this._navigate = this._navigate.bind(this);
}
To
constructor( props ){
super( props );
// The following line is not required since you are using an arrow function to call this one.
// this._navigate = this._navigate.bind(this);
}
It is because there is a mismatch between property you use in Navigator and in your component
Change
_navigate(name){
this.props._navigate.replace({ //I also tried push, same problem.
name
});
}
to
_navigate(name){
this.props.navigator.replace({ //I also tried push, same problem.
name
});
}