bluepuper
bluepuper

Reputation: 384

Condition with state doesn't work in react

I have several buttons with different values, and i need user to click them all, only then access will be provided. So it turns out that i'm using weird if statement cuz it doesn't work. This is my code:

export const SubscribeOnOthers: React.FC = () => {
  const router = useRouter();
  const [subscribed, setSubscribed] = useState<Array<string>>([]);
  const [isError, setIsError] = useState<boolean>(false);
  const [isSuccess, setIsSuccess] = useState<boolean>(false);

  const users = [
    { nickname: "@user1" },
    { nickname: "@user2" },
    { nickname: "@user3" },
    { nickname: "@user4" },
  ];

  const checkAllSubs = useCallback(() => {
    users.map(({ nickname }) => {
      if (!subscribed.includes(nickname)) {
        setIsError((prev) => true);
      }
    });
    setTimeout(() => {
      if (!isError) {
        console.log("all is good")
      }
    },1000)
  }, [isError])
  return (
    ...
  )

So i have 4 members and user have to subscribe on each member(let's think if he clicked, he subscribed) When the user click on any button, value of that button is writing to subscribed state. And when the user click on button named check all subscriptions that function checkAllSubs is called. But when i have not all users in subscribed state, router consoles "all is good" anyway in 1 sec Where is the problem

Upvotes: 0

Views: 141

Answers (1)

pepinillo6969
pepinillo6969

Reputation: 463

I think you should rethink a bit this component, I don't see why to use setTimeout but anyway, useState is not synchronous so it is still false in the if statement. Instead, use a variable as flag, not a state. And in this case also best practice to use a forEach instead of a map, because you are not returning any array.

const checkAllSubs = ()=>{
let isError=false
    users.forEach(({ nickname }) => {
      if (!subscribed.includes(nickname)) {
        IsError=true;
      }
    });
    setTimeout(() => {
      if (!isError) {
        console.log("all is good")
      }
    },1000)
  }
  return (
    ...
  )

And if you are using useCallback remember to add subscribed to your dependency array

Upvotes: 1

Related Questions