0

const [userOrderCollection, setUserOrderCollection] = useState([{
  url: null
}]);

const onAddedUserOrder = url => {
  if (userOrderCollection[0].url === url) return;
  else {
    setUserOrderCollection([{ ...userOrderCollection,
      url
    }]);
    console.log(userOrderCollection)
  }
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

But, the line is added only once, and with the first click, I get an empty array in the console, only with the second click the addition is triggered ...

2
  • 1
    I'm not sure what your state is representing. Can you try to explain a bit more what this code is meant to be doing? Commented Jan 26, 2020 at 8:36
  • I have a list with users, and when I click on them, I add links to their avatars to the array to understand which users are selected, and then send this array to the database Commented Jan 26, 2020 at 8:38

4 Answers 4

2

You're not actually adding anything to the array, you're constantly creating an array of a single element. In addition your console log will not show the updated state at that point.

Try this:

const [userOrderCollection, setUserOrderCollection] = useState([]);

const onAddedUserOrder = url => {
  if (userOrderCollection.find(user => user.url === url)) return;
  else {
    setUserOrderCollection(prev => ([ ...prev, { url } ]));
  }
};

If you want to see the state after it's been updated you should do so within a useEffect

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

Comments

1

State is updated on the next render of the component, so logging it where you do will show the previous state

Comments

0

You can't console.log right after calling the setUserOrderCollection function since it's asynchronous, calling that function only dispatches the action to take place on a later date.

On another note, to avoid race conditions, you should use the set*((value) => newValue) instead of set*(newValue).

setUserOrderCollection(userOrderCollection => [{ ...userOrderCollection,
      url
}]);

Also, if you want to add something to the array you should use something like that:

setUserOrderCollection(userOrderCollection => [...userOrderCollection, {
      url
}]);

Your code would only expand an array over the only object in an array, which probably isn't something you're looking for.

To log each state change you can use the useEffect hook, like this:

useEffect(() => console.log(userOrderCollection),
    [ userOrderCollection ]
);

Comments

0

You are using the array destruction wrong:

Change

setUserOrderCollection([{ ...userOrderCollection,
  url
}]);

to

setUserOrderCollection([
  ...userOrderCollection,
  {url}
]);

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.