-1

I have a button that if I click (which will be setting state to true), I want to set the transform value to a certain number

const [openShop, setOpenShop] = useState(false);
const [containerHeight, setContainerHeight] = useState('');
const [translateY, setTranslateY] = useState(0);

// ... more code where I set containerHeight

const onShopPress = () => {
  setOpenShop(!openShop);
  if (openShop) {
    setTranslateY(-containerHeight);
  } else {
    setTranslateY(0);
  }
  console.log('shopping pressed');
};

<TouchableOpacity style={styles.shopBtn} onPress={onShopPress}>
  <Animated.View
    style={[styles.shopBtnView, {transform: [{translateY}]}]}>
    <Text>Shop</Text>
  </Animated.View>
</TouchableOpacity>

Right now, I have to press the button twice to actually get into openShop block. The first click, it just goes to the else block.

hellomello
  • 8,219
  • 39
  • 151
  • 297

1 Answers1

2

Because setState is async, state only has new value when component rerender. So you can use another value in this case:

const onShopPress = () => {
  const newOpenSop = !openShop
  setOpenShop(newOpenSop);
  if (newOpenSop) {
    setTranslateY(-containerHeight);
  } else {
    setTranslateY(0);
  }
  console.log('shopping pressed');
};

OR

  const onShopPress = () => {
    setOpenShop(newOpenSop=>{
      setOpenShop(newOpenSop);
      if (newOpenSop) {
        setTranslateY(-containerHeight);
      } else {
        setTranslateY(0);
      }
  });
    
  console.log('shopping pressed');
};

Why is this required?

Setting a state is an async task so all the update action will go to the event loop and your next statement will be executed before this one.

This is a must-watch if you want to know about event loops https://www.youtube.com/watch?v=8aGhZQkoFbQ

Kartik Malik
  • 460
  • 4
  • 11
Viet
  • 12,133
  • 2
  • 15
  • 21
  • State updater functions ***are not*** `async` functions, they cannot be awaited. React state updates are asynchronously processed though, but saying the function is `async` will only lead to further confusion to devs new to React and hooks. – Drew Reese Aug 18 '21 at 05:45
  • we call setTimeout an asynchronous function, and they can't be awaited either. For that matter, any of the non-blocking statements are considered to be asynchronous. and we have a callback function with such statements. we have a callback function for state updater functions too. Please correct me if I stated something wrong. – Kartik Malik Aug 18 '21 at 05:58