Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用异步react功能组件或if语句_Javascript_Reactjs_If Statement_Axios - Fatal编程技术网

Javascript 使用异步react功能组件或if语句

Javascript 使用异步react功能组件或if语句,javascript,reactjs,if-statement,axios,Javascript,Reactjs,If Statement,Axios,我正在开发一个应用程序,我需要根据用户的地理位置显示货币。如果失败,我想使用函数getCountryInfoByLanguage中的数据 基本上,这段代码会运行,但不会等待if语句完成,而是使用它从函数中获得的货币,然后if语句完成并打印我想要使用的countryCode。 我有哪些选择?我尝试使用async/await,但我得到“对象作为React子对象无效(找到:[object Promise])。如果要呈现子对象集合,请改用数组。” 有多种方法可以解决这个问题。我用React钩子写了一个简

我正在开发一个应用程序,我需要根据用户的地理位置显示货币。如果失败,我想使用函数getCountryInfoByLanguage中的数据

基本上,这段代码会运行,但不会等待if语句完成,而是使用它从函数中获得的货币,然后if语句完成并打印我想要使用的countryCode。 我有哪些选择?我尝试使用async/await,但我得到“对象作为React子对象无效(找到:[object Promise])。如果要呈现子对象集合,请改用数组。”


有多种方法可以解决这个问题。我用React钩子写了一个简单的例子。在ES6类组件中也可以这样做。诀窍是保持React生命周期函数本身同步,但进行如下asyc调用:

import React from "react";
import getCountryInfoByLanguage from "./getCountryInfoByLanguage";
import axios from "axios";

function Comp({ language }) {
  const [countryCode, setCountryCode] = React.useState(null);

  React.useEffect(() => {
    (async function() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(position => {
          axios
            .get(
              `http://api.geonames.org/countryCodeJSON?lat=${position.coords.latitude}&lng=${position.coords.longitude}&username=...`
            )
            .then(response => {
              setCountryCode(response.data.countryCode);
            });
        });
      } else {
        const countryInfo = getCountryInfoByLanguage(language);
        setCountryCode(countryInfo.countryCode);
      }
    })();
  }, []);

  return <div>Your country code : {countryCode}</div>;
}
从“React”导入React;
从“/getCountryInfoByLanguage”导入getCountryInfoByLanguage;
从“axios”导入axios;
函数Comp({language}){
const[countryCode,setCountryCode]=React.useState(null);
React.useffect(()=>{
(异步函数(){
if(导航器.地理位置){
navigator.geolocation.getCurrentPosition(位置=>{
axios
.得到(
`http://api.geonames.org/countryCodeJSON?lat=${position.coords.latitude}&lng=${position.coords.longitude}&username=`
)
。然后(响应=>{
setCountryCode(response.data.countryCode);
});
});
}否则{
const countryInfo=getCountryInfoByLanguage(语言);
设置国家代码(countryInfo.countryCode);
}
})();
}, []);
返回您的国家代码:{countryCode};
}

您可以更改if{}else{}逻辑 尝试{}捕获{}逻辑

try {
 navigator.geolocation.getCurrentPosition(position => {
      axios
        .get(
          `http://api.geonames.org/countryCodeJSON?lat=${
            position.coords.latitude
          }&lng=${position.coords.longitude}&username=...`
        )
        .then(response => {
          countryCode_ = response.data.countryCode;
          console.log(countryCode_);
        });
    });
}
catch(e) {
 countryCode_ = countryCode;
}

第一个问题是这个函数没有正确地返回承诺。与设置变量countryCode_uu并修改它不同,您希望在获得最终值后使用它进行解析。你几乎不需要“国家代码”。问题是,您必须在if/else中计算这两种情况下的格式化价格。我会这样做:

import convertPrice from "./convertPrice";
import getCountryInfoByLanguage from "./getCountryInfoByLanguage";
import axios from "axios";
export default (language, price) => {
  const { countryCode, currency } = getCountryInfoByLanguage(language);

  return new Promise((resolve, reject) => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position => {
        axios
          .get(
            `http://api.geonames.org/countryCodeJSON?lat=${
              position.coords.latitude
            }&lng=${position.coords.longitude}&username=...`
          )
          .then(response => {
            // assuming this response always exists
            const geoCountryCode = response.data.countryCode;
            console.log("countryCode from geolocation:", geoCountryCode);
            resolve(getFormattedPrice(geoCountryCode));
          });
      });
    } else {
      console.log("default countryCode:", countryCode);
      resolve(getFormattedPrice(countryCode));
    }
  });
};

function getFormattedPrice(countryCode) {
  const convertedPrice = Math.round(convertPrice(price, currency) * 10) / 10;
  const formattedPrice = convertedPrice.toLocaleString(countryCode, {
    style: "currency",
    currency: currency
  });
  console.log("formattedPrice:", formattedPrice);
  return formattedPrice;
}

当使用它时,它仍然是异步的,所以无论调用它的是什么,它本身都需要是异步的,这样你就可以使用
wait
,或者你可以将它称为一个promise with.then(()=>{})。

你的react组件在哪里?哦,是的,你是对的,它不是一个组件。问题仍然存在,因为如果我尝试使用async,“对象作为React子对象无效”
import convertPrice from "./convertPrice";
import getCountryInfoByLanguage from "./getCountryInfoByLanguage";
import axios from "axios";
export default (language, price) => {
  const { countryCode, currency } = getCountryInfoByLanguage(language);

  return new Promise((resolve, reject) => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position => {
        axios
          .get(
            `http://api.geonames.org/countryCodeJSON?lat=${
              position.coords.latitude
            }&lng=${position.coords.longitude}&username=...`
          )
          .then(response => {
            // assuming this response always exists
            const geoCountryCode = response.data.countryCode;
            console.log("countryCode from geolocation:", geoCountryCode);
            resolve(getFormattedPrice(geoCountryCode));
          });
      });
    } else {
      console.log("default countryCode:", countryCode);
      resolve(getFormattedPrice(countryCode));
    }
  });
};

function getFormattedPrice(countryCode) {
  const convertedPrice = Math.round(convertPrice(price, currency) * 10) / 10;
  const formattedPrice = convertedPrice.toLocaleString(countryCode, {
    style: "currency",
    currency: currency
  });
  console.log("formattedPrice:", formattedPrice);
  return formattedPrice;
}