-1

I have defined useState hook like the following. And the function handleDownloadClick is triggered when a user hits a button on the UI in my app (code not shown for breivity purpose).

When the control reaches else block, I am trying to set the downloadData which is an object to the variable selectedAsset like this setSelectedAsset(downloadData);. However, console.log(selectedAsset[0]); always prints undefined. What am I doing wrong here? Is the way I have defined the useState for an object correct?

const [selectedAsset,setSelectedAsset] = useState({});

const handleDownloadClick = (downloadData, e) => {
    
    console.log("Inside Download button");
    console.log(downloadData);
    if(![1,2].includes(downloadData.assetCategoryId)) 
    { 
               
              
     }
    else {
            console.log("June 23: Testing Inside Else statement");
            console.log(downloadData);
          
             setSelectedAsset(downloadData);
             console.log("Testing selectedAsset[0] value");
             console.log(selectedAsset[0]);
                 
          


     }

For reference:

console.log(downloadData); looks like following in the browser's console:

Object { id: 1234, assetsTypeId: -1, fileName: "encounters_1624466728211.csv", locationTypeId: 1, path: null, fullPathName: "/mnt/nfs/Data/dev/data/encounters_1624466728211.csv", ubriteUri: null, fileVersion: null, fileEncodingId: null, ownerId: 123, … }

Tan
  • 1,433
  • 5
  • 27
  • 47

1 Answers1

1

Your state definition is fine. Your problem is you didn't consider component updates.

When you set a new value to a state, the whole component will rerender with your new state value.

Your problem can be solved by adding a useEffect hook to your state. Like this:

    const [selectedAsset,setSelectedAsset] = useState({});

    useEffect(()=>{
            console.log("Testing selectedAsset value");
            console.log(selectedAsset);
    },[selectedAsset])

    const handleDownloadClick = (downloadData, e) => {
        
            console.log("Inside Download button");
            console.log(downloadData);
            if(![1,2].includes(downloadData.assetCategoryId)) 
            { 
                   
                  
            }
            else {
                console.log("June 23: Testing Inside Else statement");
                console.log(downloadData);
                setSelectedAsset(downloadData);  
         }
    }

And then whithin this callback you can check your newly selectedAsset value

FMoosavi
  • 150
  • 1
  • 11
  • Thanks. So above useEffect hook will go inside `else` block? Because doing this is causing `Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:` error – Tan Jun 23 '21 at 19:48
  • Of course not! Take a look at the documentation. https://reactjs.org/docs/hooks-effect.html It will go within the main component function. – FMoosavi Jun 23 '21 at 19:53
  • Yes, I have seen that. Would you mind modifying my code and put the useEffect where it is intended to be in your answer? – Tan Jun 23 '21 at 19:54
  • Of course. Here you go. – FMoosavi Jun 23 '21 at 19:59
  • Thanks but the console.log inside useEffect is still showing `undefined`. – Tan Jun 23 '21 at 20:06
  • You have set an object to selectedAsset. Then by calling selectedAsset[0] you're using it as an array! It's hard to solve your problem without seeing your code! – FMoosavi Jun 23 '21 at 20:23
  • I have used `selectedAsset[0]` because of the following :`When the hook useState(initialState) is invoked, it returns an array. ` Source : 1.3 Reading Section. https://dmitripavlutin.com/react-usestate-hook-guide/ Please let me know if I misunderstood something. – Tan Jun 23 '21 at 20:27
  • useState returns an array of two items. First one is the state value itself. Second one is the setter function of it. this article you mentioned didn't spread array items and used them as one array named stateArray. Which means stateArray[0] is the value itself and the stateArray[1] is the setter function of it. Your code is not like this article. You didn't use it as one single array – FMoosavi Jun 23 '21 at 20:36
  • Ok. Thanks for explanation. What should I be calling instead of `selectedAsset[0]`? – Tan Jun 23 '21 at 20:41
  • @Ten done it... – FMoosavi Jun 23 '21 at 20:45
  • Thanks very much. It is working now. – Tan Jun 23 '21 at 20:53