Home > Enterprise >  React update state after updating a different one in useEffect
React update state after updating a different one in useEffect

Time:05-23

I need to update my state after updating / setting a different state in my useEffect hook. So far it does not work. What am I doing wrong here?

The isDisabled logic depends on the values of the other states.

const OffersDialogueButton = ({
  type,
  status,
}) => {
  const { invitationType, status: cardStatus } = useJobPositionsContext();
  const { jobPosition } = useJobDetailContext();
  const [dialogStatus, setDialogStatus] = useState<CardStatus>();
  const [dialogType, setDialogType] = useState<CardType>();
  const [color, setColor] = useState<string>();
  const [isDisabled, setIsDisabled] = useState(false);

  useEffect(() => {
    setDialogStatus(status || cardStatus);
    setDialogType(type || invitationType || 'default');
    setIsDisabled(
      (dialogType === 'invitation' && dialogStatus !== 'pending') || (dialogType === 'application' && cardStatus !== 'accepted'),
    );
    setColor(BUTTON_VARIANT_BY_STATUS[dialogStatus]);
  }, [type, status, isDisabled]);

CodePudding user response:

dialogType and dialogStatus are set in the same function with state set which is async so you cannot expect them to be set when you check them in the same function. You should have a new useEffect for those variables or have a local variable for the checks.

CodePudding user response:

As I understand you want to make setIsDisabled by setDialogType , you need to use other useEffect

React.useEffect(() => {
    setIsDisabled(
      (dialogType === 'invitation' && dialogStatus !== 'pending') || (dialogType === 'application' && cardStatus !== 'accepted'),
    );
  }, [dialogType])

setDialogType is asynchronous , you can not access it immediately after the setState.

Read more about React state here State

CodePudding user response:

When computing isDisabled and color state variables, you must use the new values of dialogStatus and dialogType.

const OffersDialogueButton = ({type, status}) => {
  const { invitationType, status: cardStatus } = useJobPositionsContext();
  const { jobPosition } = useJobDetailContext();
  const [dialogStatus, setDialogStatus] = useState<CardStatus>();
  const [dialogType, setDialogType] = useState<CardType>();
  const [color, setColor] = useState<string>();
  const [isDisabled, setIsDisabled] = useState(false);

  useEffect(() => {
    const nextDialogStatus = status || cardStatus;
    const nextDialogType = type || invitationType || 'default';
    const nextIsDisabled = 
      (nextDialogType === 'invitation' && nextDialogStatus !== 'pending') || 
      (nextDialogType === 'application' && cardStatus !== 'accepted');
    const nextColor = BUTTON_VARIANT_BY_STATUS[nextDialogStatus];

    setDialogStatus(nextDialogStatus);
    setDialogType(nextDialogType);
    setIsDisabled(nextIsDisabled);
    setColor(nextColor);
  }, [status, cardStatus, type, invitationType]);
  • Related