2

Here I am passing state up via props through an intermediary component. The intermediate component has a handler (onIntermediatePropsHandler) has some logic (const formatedAmount = enteredAmount += 10;) that executes on the data being passed. It would seem that the logic only executes once. Why is this?

const Parent = () => {

  const onParentPropsHandler = amount => {
    console.log(amount)
  }

  return (
    <div>
      <Intermediate IntermediateToParent={onParentPropsHandler} />
    </div>
  )
}

const Intermediate = (props) => {

  const onIntermediatePropsHandler = enteredAmount => {
    const formatedAmount = enteredAmount += 10;
    props.IntermediateToParent(formatedAmount)
  }

  return (
    <div>
      <Child ChildToIntermediate={onIntermediatePropsHandler} />
    </div>
  )
}

export const Child = (props) => {
  const [index, setIndex] = useState(null)

  const onClickHandler = (index) => {
    setIndex(index + 1);
    props.ChildToIntermediate(index);
  }

  return (
    <div>
      <button onClick={() => onResetState(index)}>Reset Counter</button>
    </div>
  )
}

This gives the console log of

enter image description here

Byron
  • 75
  • 9
  • 1
    Seems like your code is not complete since the onClickHandler function is never used? – Andreas Jagiella Jan 12 '22 at 11:42
  • You are adding 10 every time, but your original state isn't affected, you are basically doing: 1+10, 2+10, 3+10 (Also, because you set state immediately before calling `ChildToIntermediate`, you are logging the previous value each time as the async state hasn't caught up yet) – DBS Jan 12 '22 at 11:42
  • I don't understand your issue. What do you try to achieve here? – TheTisiboth Jan 12 '22 at 11:51
  • Hey Tisiboth. So yes the onclick handler not being called is a mistake created in the preparation of the snippet for stack overflow. My aim was to complete a small exercise in passing up state through a few component levels. I realise a central state store may be a better idea. I suppose I'm trying to get my head round where to put state, where to change it and how to pass it through components. – Byron Jan 12 '22 at 12:19

2 Answers2

1

I'm not sure what you are trying to achieve here. But in case you want to format the index before setting the index in the children local state, then you should call the parent function before setting the index, like this:

const Intermediate = (props) => {
  const onIntermediatePropsHandler = (enteredAmount) => {
    const formatedAmount = (enteredAmount += 10);
    props.IntermediateToParent(formatedAmount);
    return formatedAmount // Return the formated Amount to the children
  };

  return (
    <div>
      <Child ChildToIntermediate={onIntermediatePropsHandler} />
    </div>
  );
};

export const Child = (props) => {
  const [index, setIndex] = useState(null);

  const onClickHandler = (index) => {
    const updatedIndex = props.ChildToIntermediate(index); // You get the updated index
    setIndex(updatedIndex + 1);
  };

  return (
    <div>
      <button onClick={() => onClickHandler(index)}> Counter: {index}</button>
    </div>
  );
};
TheTisiboth
  • 1,431
  • 1
  • 6
  • 13
1

I am not sure what you are trying to do. But if you want to format the updated index, you should call the parents function in the useEffect function, because index is set asynchronously, so you are getting the old state. So your child state will look like this:

  useEffect(() => {
    props.ChildToIntermediate(index); // Updated index value
  });

  const onClickHandler = (index) => {
    setIndex(index + 1);
  }

This way, after updating your index, you will call the parent function, according to the updated index (and not anymore with the old state)

TheTisiboth
  • 1,431
  • 1
  • 6
  • 13
  • Ahhh thank you that is why it doesn't increment..... because your not updating the state? – Byron Jan 12 '22 at 12:24
  • setIndex is asynchronous. Therefore, you cannot use the index directly after setting it. To get the asynchronous updated index, you have to get it through useEffect, because it will be triggered everytime the state is updated. Take a look at the doc if you want to dig into it: https://reactjs.org/docs/hooks-effect.html – TheTisiboth Jan 12 '22 at 13:00