как добавить весь массив в переменную useState - PullRequest
2 голосов
/ 11 октября 2019

Я пытаюсь добавить целый массив в переменную useState, но продолжаю получать значение null, программа должна делать то, что сначала она проверяет, доступна ли студия по умолчанию, и добавляет это в defaultStudioAvailable, а затем принимаетэта студия выходит из массива studios, а затем еще раз проверяет все остальные студии и добавляет их в массив others с помощью строки others [studio] = res;и добавляет, что для изменения состояния otherStudiosAvailable, однако я получаю правильные данные в массиве others, но ничего не добавляется в массив состояния otherStudiosAvailable,

Может кто-нибудь увидеть, что я делаю неправильно? любая помощь будет оценена.

const Home = ({i18n}) => {

  const [defaultStudioAvailable, setDefaultStudioAvailable] = useState();
  const [otherStudiosAvailable, setOtherStudiosAvailable] = useState([]);

  const studios = ["de", "fr", "pl", "en", "nl", "ru"];
  const otherStudios = studios.filter(item => {
    return item !== i18n.language;
  });

 useEffect(() => {

 let others = [];

    checkForAvailableAgent(
      `sales_${i18n.language}`,
      "LinkToStudio",
      "ServiceID"
    )
      .then(res => {
        setDefaultStudioAvailable(res);
      })
      .catch(error => {
        console.log("an error happened.");
      });

   for (const studio of otherStudios) {
      checkForAvailableAgent(
        `sales_${studio}`,
        "LinkToStudio",
        "ServiceID"
      )
        .then(res => {
          // this has the correct values
          others[studio] = res;
          // this keeps being null even though others have values
          setOtherStudiosAvailable(others);
        })
        .catch(error => {
          console.log("an error happened.");
        });
    }

    console.log("others[studio]: ", others);
    console.log("other studios available: ", otherStudiosAvailable);
  }, [defaultStudioAvailable, i18n.language]);
}

// console output

others[studio]:  [en: false, fr: false, nl: false, pl: false, ru: false]

other studios available:  []




{defaultStudioAvailable ? (
        <Button
          variant="success"
          className="btn-xlarge"
          onClick={e => callBtnClick("direct")}
        >
          {t("callBtn")}
        </Button>
       ) : otherStudiosAvailable ? (
       <Button
          variant="success"
          className="btn-xlarge"
          onClick={e => callBtnClick("flag")}
        >
          Other studios available
        </Button>
      ) : (
    ""
  )}

Ответы [ 2 ]

1 голос
/ 11 октября 2019

проблема в асинхронном характере useState fns

Вы находитесь в console.log() внутри того же самого useEffect () до того, как setState fn обновит значение.

useEffect(() => {
 let others = [];
 checkForAvailableAgent(
      `sales_${i18n.language}`,
      "LinkToStudio",
      "ServiceID")
   .then(res => { setDefaultStudioAvailable(res); })
   .catch(error => { console.log("an error happened."); });

 for (const studio of otherStudios) {
   checkForAvailableAgent(
        `sales_${studio}`,
        "LinkToStudio",
        "ServiceID"
   )
   .then(res => {
       others[studio] = res; // here you are not using the updated value anywhere, so no problem here
      setOtherStudiosAvailable(others); // the asynchronous setState has been called, the callback can be obtained with a useEffect on the updated state value
   })
   .catch(error => {console.log("an error happened."); });
 }
    console.log("others[studio]: ", others); //using a local variable, should log fine
    console.log("other studios available: ", otherStudiosAvailable); // the otherStudiosAvailable has not been updated yet., uses the previous value []
  }, [defaultStudioAvailable, i18n.language]);
}

Чтобы получить значениепосле его обновления используйте Effect on otherStudiosAvailable

useEffect(() => console.log(otherStudiosAvailable), [otherStudiosAvailable])

Обновление

Вместо нескольких условных операторов было бы лучше упростить структуру как

{defaultStudioAvailable && (
        <Button
          variant="success"
          className="btn-xlarge"
          onClick={e => callBtnClick("direct")}
        >
          {t("callBtn")}
        </Button>
       )}
{otherStudiosAvailable&& otherStudiosAvailable.length && ( //otherStudiosAvailable is an [] and always truthy
       <Button
          variant="success"
          className="btn-xlarge"
          onClick={e => callBtnClick("flag")}
        >
          Other studios available
        </Button>)}

В вашем коде otherStudiosAvailable был в else части троичного оператора, поэтому даже если он имеет значения, он не запустится, если defaultStudioAvailable верен

0 голосов
/ 11 октября 2019

defaultStudioAvailable находится в вашем списке зависимостей, и вы изменяете его значение в useEffect с помощью setDefaultStudioAvailable (res), это должно вызвать бесконечный цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...