NatMargo
NatMargo

Reputation: 21

how to make a touchable opacity from a child component change the state in a parent component (hooks)

I am trying to build a calculator app in react native.

I have a touchableopacity button in a child component in a separate js file from the parent component. When I press that button I want the state in the parent component to be updated to show a new value.

in my child component i have this:

export default function CalculatorButton(props) {

  return (
    <View style={styles.container}>
      <TouchableOpacity style={[styles.buttonContainer, { backgroundColor: props.color}]} onPress={() => {props.callback}}>
        <Text style={styles.buttonText}>{props.children}</Text>
      </TouchableOpacity>
    </View>
  );
}

then in the parent component i add it in like this:

 return (
    <View style={styles.container}>
      <Card style={{padding: 10, margin: 10, height: 50}}>
        <View style={styles.outputView}>
          <Text style={styles.outputText}>{value}</Text>
        </View>
      </Card>
      <View style={styles.buttonCol}>
        <View style={styles.buttonRow}>
          <CalculatorButton color={morningBlue} num={"7"} callback={app}>7</CalculatorButton>
          </View>
      </View>
      <Text style={styles.paragraph}>
      </Text>
      
    </View>
  );

and i want the touchable opacity to run a function something like this:

      var finalNum = value
      if (value == "0") {
        finalNum = newNum;
      } else {
        finalNum = value + newNum
      }
      setValue(finalNum)

to change the value useState in the parent component where the display screen is.

I tried to pass the function as a prop (or callback?) but I either get the infinite loop error cause it keeps trying to run the function when i pass it or I am unable to call the function in the onClick of my touchable opacity.

I could technically put everything into one file instead of having child component so the touchable opacity can directly run the function to change the usestate value, but I wanted to try refactoring it out and am not sure what is the proper way to fix it

All the examples I found so far for this use class base components for React but I want to use function based components for React Native and I don't understand how to convert it to function based component code

Upvotes: 0

Views: 731

Answers (1)

YaNuSH
YaNuSH

Reputation: 1097

  • Define your initial state and the setter for it in the parent component, for example const [freeText, setFreeText] = useState('initial text');
  • In your parent component, define a function that changes the state. call it "changeParentState" for example and make it use setFreeText to set a new state as you wish, for example: changeParentState() { setFreeText('new value')}
  • Pass this function as a prop to your child component: callback={()=>changeParentState()}
  • Whenever you press the child component, it will call the function from the parent component.
  • Don't forget to use the value from the state as prop for your child component. num={"7"} should be probably changed to num={freeText}

Upvotes: 1

Related Questions