0

I am creating a pluggable widget for Mendix and am having some trouble using useState. I am trying to initialize useState using a function to create and return Array of Objects. Despite the function working as intended, my useState never get's updated and always remains as an empty array.

This is my code:

const [data, setData] = useState<Data[]>(getData); 


    function getData() {

        let dataArray: Data[] = [];
        
        props.data.items?.map((item) => {

            dataArray.push({
                id: props.id.get(item).value?.toNumber(),
                Name: props.name.get(item).value?.toString(), 
                Status: props.status.get(item).value?.toString(), 
                clicked: false,
            })
        })
        
        return dataArray;
    }

I am using TypeScript, and have created a type interface for my useState:

export interface Data {
     id?: Big | number, 
     Name?: string; 
     Status? : string; 
     clicked : boolean;
     LinkedData?: [
        {
            id: Big; 
            Name : string,
            Status? : string
        }
    ] 
}

I am not getting any errors in my files, nor in my console, but useState never gets updated. The data being accessed within the function is data passed to the widget.

What could I be doing wrong?

5
  • When I test on my end, it is working, when I hard code some values in dataArray. So if your array remain empty, it is certainly because props.data.items is empty. In this case, dataArray remains empty as well Commented Jan 23, 2024 at 16:21
  • Take a look at this answer: stackoverflow.com/questions/55621212/… Commented Jan 23, 2024 at 16:53
  • @TheTisiboth Thanks for the reply! The problem does seem to be that the data hasn't loaded yet. Because I'm working with Mendix I am not doing a fetch to retrieve the data however. In my situation I can check whether the data is "available" using datasource.status, but I am not sure how to use this to 'wait' for the data to be available. A while loop results in an infinate loop because the status is always returned as "loading". Creating an onClick function that updates the state does work, but that's obviously not an ideal solution. Commented Jan 24, 2024 at 11:21
  • Well, you should edit your post by providing more context on the error. Also providing a minimal reproducible example (with codesanbox for instance) would be ideal. But right now it is difficult to debug the problem without more context Commented Jan 24, 2024 at 12:58
  • Also, what do you mean by: Despite the function working as intended? Commented Jan 24, 2024 at 13:02

1 Answer 1

0

I would initialize the state with an empty array and then, in a useEffect set the actual data. As the dependency array you can use [props.data.items, props.id, props.name, props.status].

That way, when the data becomes available, the state will be (re)set.

Also, I would change this:

props.data.items?.map((item) => {
        dataArray.push({
            id: props.id.get(item).value?.toNumber(),
            Name: props.name.get(item).value?.toString(), 
            Status: props.status.get(item).value?.toString(), 
            clicked: false,
        })
    })

To:

upadatedData = props.data.items?.map((item) => {
        return {
            id: props.id.get(item).value?.toNumber(),
            Name: props.name.get(item).value?.toString(), 
            Status: props.status.get(item).value?.toString(), 
            clicked: false,
        };
    });

And then set the state to updatedData. You are using map after all... otherwise you could just as well do a forEach (which is less elegant here).

Also, you can add a guard clause in your useEffect to only update when everything is available.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.