lwisi
lwisi

Reputation: 303

Responding to changes in the state of a child component

Background

I'm building a counter component for my app. This counter is a small component which allows the user to add or remove a product from their cart. This is the way I've coded it:

export default function MenuCounter () {
    const [count, setCount] = useState(0);
    
return ( 
    
    <View style={styles.adder}>
        <TouchableOpacity onPress={() => {count === 0 ? setCount(count) : setCount(count - 1)}}>
            <Text style={styles.less}>-</Text>
        </TouchableOpacity>
        <Text style={styles.counter}>{count}</Text>
        <TouchableOpacity onPress={() => setCount(count + 1)}>
            <Text style={styles.more}>+</Text>
        </TouchableOpacity>
    </View>

)
}

What I have tried

I've tried handling the change with a function and an onChange={} method. Code looks like this:

const [amount, setAmount] = useState(0)

      const handleStateChange=()=>{
        amount = count;
        setAmount(amount)
        
      }

And then

<MenuCounter onChange={handleStateChange}/>

Of course, this doesn't work, but I have no clue on how to fix it.

Question

How can I listen to state changes in a child component in order to be able to use it in its parent?

Edit 1:

Forgot to mention that the MenuCounter is rendered within a FlatList item. That was the initial reason I had the state in the child rather than the parent. The answers provided so far (9/12/18 10:17) update every component at the same time.

Upvotes: 0

Views: 74

Answers (2)

Shushanth Pallegar
Shushanth Pallegar

Reputation: 2862

It's better to use MenuCounter as child component which receives props from the parent component and child component can handle props and invoke parent methods ( as per your requirements) to update the counter as below.

Parent Component


export default ParentComponent = () => {
  const [count, setCounter] = useState(0);
  const updateCounter = () => {
    //logic
    //setCounter(count + 1);
    // setCounter(counter - 1);
  }
  return (
    <div>
      <MenuCounter updateCounter={updateCounter} count={count}/>
    </div>
  );
}

Child component (MenuCounter)


export default MenuCounter = ({count, updateCounter}) => {
    <View style={styles.adder}>
        <TouchableOpacity onPress={() => updateCounter()}>
            <Text style={styles.less}>-</Text>
        </TouchableOpacity>
        <Text style={styles.counter}>{count}</Text>
        <TouchableOpacity onPress={() => updateCounter()}>
            <Text style={styles.more}>+</Text>
        </TouchableOpacity>
    </View>
  }

MenuCounter.propTypes = {
  count: PropTypes.string,
  updateCounter: PropTypes.func
};

Upvotes: 2

Erik Dreifaldt
Erik Dreifaldt

Reputation: 783

Create a function in your parent

const change_amount = () => {
// CODE: Increase amount by 1
setAmount((value) => value + 1)
}

which you pass to in the components onPress={()=>{change_amount()}}

edit: or return a value from the child component

Upvotes: 0

Related Questions