Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

useEffect uses old value

please help. When function "handleAddToken" is triggered, useEffect uses the previous old state of tokenData, instead of the new one.
It results in tokens being added in a desynchronized way (zero tokens after I add 1st token, then 1st token and I added 2nd token, etc)

Here’re all of the states:

  // this one opens modal window where you enter values which go inside token data
  const [open, setOpen] = React.useState(false);
  
  // this one is to set data inside token {}
  const [tokenData, setTokenData] = React.useState({});

  // this one is a token that is added inside the array of tokens, which then is mapped as elements
  const [token, setNewToken] = React.useState<JSX.Element>();
  

The useEffect:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  React.useEffect(() => {
    // tokenId is undefined at the beginning, but is defined after handleAddToken is called (see below)
    if ((tokenData as TokenData).tokenId) {
      // assembleToken returns a JSX Element that is assembled with tokenData
      setNewToken(assembleToken(tokenData as TokenData));

      // adds token inside array of other tokens (addToken is a useState state setter from another module)
      props.addToken([...props.tokenArray, token]);

      // to reset tokendata
      setTokenData({
        tokenTrueName: "",
        tokenAlias: null,
        tokenId: "",
        tokenType: "",
        tokenLabelColor: "",
        tokenStatusColor: "",
        linkedTo: null,
        tokenInitiative: 0,
        tokenHP: "",
        tokenDefense: "",
        tokenSpeed: "",
      });
    }
  }, [tokenData, token]);

This function is called, when I click the "Add token" button.

  function handleAddToken() {

    // adds additional data (other data, like tokenAlias ot trueName is being added onChange, that is triggered when you type in fields within a modal window, I didn't include this function here)
    setTokenData({
      ...tokenData,
      tokenId: uuidv4(),
      tokenType: currentTokenType,
      tokenLabelColor: randomColor(),
      tokenStatusColor: "gray",
      linkedTo: null,
    });

    // closes MUI modal window
    setOpen(false);
  }

Whatever I tried didn’t work, unfortunately

>Solution :

when you use a setState function and you try to get the new state in the same scope it won’t work because the state is async, in this case you need to separate in two useEffects

React.useEffect(() => {
    // tokenId is undefined at the beginning, but is defined after handleAddToken is called (see below)
    if ((tokenData as TokenData).tokenId) {
      // assembleToken returns a JSX Element that is assembled with tokenData
      setNewToken(assembleToken(tokenData as TokenData));

      // to reset tokendata
      setTokenData({
        tokenTrueName: "",
        tokenAlias: null,
        tokenId: "",
        tokenType: "",
        tokenLabelColor: "",
        tokenStatusColor: "",
        linkedTo: null,
        tokenInitiative: 0,
        tokenHP: "",
        tokenDefense: "",
        tokenSpeed: "",
      });
    }
  }, [tokenData]);

useEffect(() => {
   props.addToken([...props.tokenArray, token]);
}, [token])
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading