1

I want to prompt users to get input onPress but returning JSX from an onPress never worked so whats a possible workaround to return JSX based on button click. Here's my code:

import React, { useState } from 'react';
import {
    StyleSheet,
    KeyboardAvoidingView,
    View,
    Text,
    TouchableOpacity
} from 'react-native';
import InputPrompt from './InputPrompt' 

const Newact = (props) => {
  const [visible, setVisible] = useState(false)
    return(
        <View>
            <View style={styles.button} >
            <TouchableOpacity  style={styles.center} onPress={getTitle}>
                    <Text style={styles.plusSign}>+</Text>
                    </TouchableOpacity>
            </View>
        </View>
    );
}
 
const getTitle = () =>{
  return(
    <InputPrompt />
  )
}

Update:

Now thats how my code looks:

const Newact = props => {

  const [prompt, setPrompt] = useState(false);

    return(
            <View style={styles.button} >
            <TouchableOpacity  style={styles.center} onPress={() => setPrompt(true)}>
                    <Text style={styles.plusSign}>+</Text>
                    </TouchableOpacity>
                   {prompt ? <InputPrompt setPrompt={setPrompt} />  : null}
            </View>
    );
}

and InputPrompt component is:

const InputPrompt = (props) => {
    const [name, setName] = useState('');

    return(
        <View>
        <DialogInput 
                     title={"New Activity"}
                        submitText={"Add"}
                        hintInput ={"Enter activity name....."}
                        submitInput={ (inputText) => {setName(inputText), props.setPrompt(false)} }
                        closeDialog={ () => {props.setPrompt(false)}}>
        </DialogInput>
        <Text>{name}</Text>
        </View>
    );
}
Omar Odaini
  • 101
  • 1
  • 7

3 Answers3

4

When they press, you should set state. This causes the component to rerender, and on that new render you can return JSX describing what you want the screen to look like. I'm not sure exactly where you want to render the input prompt, but maybe something like this:

const Newact = (props) => {
    const [visible, setVisible] = useState(false)
    const [prompt, setPrompt] = useState(false);
    return (
        <View>
            <View style={styles.button} >
            <TouchableOpacity style={styles.center} onPress={() => setPrompt(true)}>
                <Text style={styles.plusSign}>+</Text>
            </TouchableOpacity>
            </View>
            {prompt && <InputPrompt />}
        </View>
    );
}
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • You're amazing!! thanks for the fast response its working. – Omar Odaini Jul 05 '20 at 15:48
  • as a follow up, I see that the prompt is only populated on the first click. How can I include a reset to the var `prompt`? something like `{prompt ? && setPrompt(false) : null}` – Omar Odaini Jul 05 '20 at 18:30
  • Depends what condition you want to reset it. If the same TouchableOpacity should be able to hide it if it's currently showing, then change it's onPress to `onPress={() => setPrompt(!prompt)}`. If a different press is supposed to hide it, then write an onPress for that component which calls `setPrompt(false)`. Or maybe it's supposed to go away based on a time, in which case you'd use an effect. There's many options, depending what your goal is. – Nicholas Tower Jul 05 '20 at 21:05
  • @OmarOdaini then select the answer as the correct one – pmiranda Jul 10 '20 at 07:47
1

Updating the state onPress is a simple way of achieving this as it will then re-render the component and you can run any jsx based on that state that you updated.

You can use a ternary expression {isPressed ? <return your jsx here> : null}

this is what it will look like in your case

const Newact = (props) => {
    const [visible, setVisible] = useState(false)
    const [prompt, setPrompt] = useState(false);
    return (
        <View>
            <View style={styles.button} >
            <TouchableOpacity style={styles.center} onPress={() => setPrompt(true)}>
                <Text style={styles.plusSign}>+</Text>
            </TouchableOpacity>
            </View>
            {prompt ? <InputPrompt /> : null}
        </View>
    );
}
Nisa
  • 21
  • 2
0

You need to change your code to something like this:

const Newact = props => {
  const [visible, setVisible] = useState(false);

  const getTitle = () => {
    setVisible(true);
  }

  return (
    <View>
      <View style={styles.button}>
        <TouchableOpacity style={styles.center} onPress={getTitle}>
          <Text style={styles.plusSign}>+</Text>
        </TouchableOpacity>
        {
          visible && <InputPrompt />
        }
      </View>
    </View>
  );
};
Taghi Khavari
  • 6,272
  • 3
  • 15
  • 32