0

I've found a few similar questions on thit topic but they're usually about React and not React Native specifically and I'm finding it a bit difficult to translate them as very new to both coming from an Android/Java background. I've a component that holds a plus and a minus icon to increase/decrease their counter. This component is used multiple times however, and I don't want to have a total and a setTotal for each instance of this component so that each can have their own total updated independently of any of the other components. At the moment, they all update when I click any of the plus/minus signs. I'm using hooks.

const [total, setTotal] = useState(0)

const increase = () => {
    setTotal(total + 1)
}

const decrease = () => {
    setTotal(total - 1)
}

...

            <Reportable
                title={'First'}
                decrease={decrease}
                increase={increase}
                total={total}
                onPress={handleChange}
            />
            <Reportable
                title={'Second'}
                decrease={decrease}
                increase={increase}
                total={total}
            />

Thanks very much.

Francislainy Campos
  • 3,462
  • 4
  • 33
  • 81

2 Answers2

2

The problem is you are passing to both component the same state (total). So, it doesn't matter who had incremented it or decremented it... they will share the values because both are using same state.

If each component needs to be aware of how many times it was incremented, you should create a state for the component itself like so:

import React from 'react';
import { View, Button } from 'react-native';

export default function Reportable() {
  const [total, setTotal] = useState(0)

  const increase = () => {
    setTotal(total + 1)
  }

  const decrease = () => {
    setTotal(total - 1)
  }

  return (
    <View>
      <Button onPress={increase} >Increment</Button>
      <Button onPress={decrease} >Decrement</Button>
    </View>
  );
}

Now import Reportable in the App.js like so:

import React from 'react';
import { View } from 'react-native';

import Reportable from './Reportable';

export default function App () {
  return (
    <View>

      {/* This is the first Reportable */}
      <Reportable />

      {/* This is the second Reportable */}
      <Reportable />

    </View>
  );
}

Now, if you need to get each count in the App.js give us more detail about what you're trying to implement so we can come up with a solution that fits your problem.

  • Hi! Thanks so much for your answer. For some reason I'd understood state had to be managed outside the component and passed as a props so the parent caller would be the one handling this for them but maybe I'd misunderstood this part. The thing is that after I'd need to add all of those individual totals together, that's why may still need to get hold of them under the parent caller at some point? Almost like I have 5 apples, 2 bananas and 3 oranges but then need to check how many fruit. In the meantime, I'm upvoting the answer as it's definitely very helpful. – Francislainy Campos May 04 '20 at 18:18
  • Okay. I'm supposing that you need the total count of all counters in the App.js file so you can use your previous solution to overcome your new problem. – edilsonlm217 May 04 '20 at 18:28
  • Create in the app.js a state to sum all counters value and pass the setState to the children and work the count there – edilsonlm217 May 04 '20 at 18:53
  • Thank you! That worked. Got something like ```const increase = () => { setTotal(total + 1) props.increase() }``` on my Reportable component and all good now. Cheers! – Francislainy Campos May 05 '20 at 04:41
  • @edilsonlm217 Hi I think I am having the same problem. However, I don't quite know hot to pass this increase function from this component to my App.js. When I use it throws me undefined error. It makes sense since increase doesn't exist in my App.js yet. Could you provide some insight? – yaozhang Apr 18 '21 at 17:56
0

As per @edilsomm217's answer, this is a sample for what worked for me.

import React from 'react';
import { View, Button } from 'react-native';

export default function Reportable() {
  const [total, setTotal] = useState(0)

  const increase = () => {
    setTotal(total + 1)
    props.increase()
  }

  const decrease = () => {
    setTotal(total - 1)
    props.decrease()
  }

  return (
    <View>
      <Button onPress={increase} >Increment</Button>
      <Button onPress={decrease} >Decrement</Button>
    </View>
  );
}

Now import Reportable in the App.js like so:

import React from 'react';
import { View } from 'react-native';

import Reportable from './Reportable';

export default function App () {
  return (
    <View>

      {/* This is the first Reportable */}
      <Reportable 
       increase={increase}
       decrease={decrease}
       />

      {/* This is the second Reportable */}
      <Reportable
       increase={increase}
       decrease={decrease}
      />

    </View>
  );
}

So I can both update the total individually as also getting the amount combined for all the items together when doing something like <Text>{total}</Text> under either the Reportable.js file or App.js respectively.

Francislainy Campos
  • 3,462
  • 4
  • 33
  • 81