0

I am trying to update an object array but even though the correct values are passed to the function, the array remains blank. If I try add a second object, then somehow the first one gets added and I'm not sure what I'm doing wrong.

 const [qualifications, setQualifications] = useState([{}]);

  function handleAddQualification(values: any) {
    console.log(values);

    console.log(qualifications);

    setQualifications((prev) => {
      return [...prev, values];
    });

    console.log(qualifications);
  }

The values that I'm passing get logged correctly and the 2 subsequent logs of qualifications both show an empty array of objects.

I simplified the object so in my screen shot I added 'one' and the value logs correctly, but the qualifications array remains blank. If I add a second entry of 'two' then for some reason it adds 'one' to the array.

Please share some insight as to what is going on here?

adding 'one'

adding 'two'

2
  • 1
    setState won't update immediately. what is the use case here? can you include some more code? Commented Jul 8, 2021 at 11:40
  • CAn you mention the final expected state here? Also, as Sarun mentioned, immediately logging after state change will not print correct values Commented Jul 8, 2021 at 11:43

2 Answers 2

1

Here is example how event loop works :)

In your case:

  1. Calling handleAddQualification
  2. Log values, qualifications
  3. Adding setQualifications to queue as async operation
  4. Log qualifications again with the same result as from step 3
  5. Here can works tasks from queue which was added before setQualifications
  6. setQualifications updates qualifications

Take a look here for better understanding https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

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

Comments

0

The state update calls are asynchronous and you can't see them by logging just after update call.

  1. The first object is empty because you have defined it in your default state and you update your new state using the previous state because of this the empty object always stays as first element in the array. To fix this set your qualifications to
interface Qual {
  subject?: string;
  level?: string;
  other?: string
}
const [qualifications, setQualifications] = useState<Qual[]>([]);
  1. if you want to log state whenever it updates use an effect hook, something like this
useEffect(() => { 
    console.log({qualifications});
}, [qualifications])

3 Comments

If I initialize the array as empty, then I get a typescript error 'Argument of type '(prev: never[]) => any[]' is not assignable to parameter of type 'SetStateAction<never[]>'. Type '(prev: never[]) => any[]' is not assignable to type '(prevState: never[]) => never[]'. Type 'any[]' is not assignable to type 'never[]'.'
This fixed it! Thanks again for your help. const [qualifications, setQualifications] = useState<object[]>([]);
I have updated the code to suit your use case but you can change the interface as you like

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.