【问题标题】:How do I set JS variable from promise within map?如何从地图中的承诺中设置 JS 变量?
【发布时间】:2020-07-08 05:41:25
【问题描述】:

我正在研究 Ionic 4 和 React,我正在尝试从函数中获取数据以返回页面,但我无法从承诺中获取数据。

仅供参考,我正在使用 react 的功能版本/模式。

participants.map(participant => {

    var paymentStatus = false;
    fetchSelectedPaymentEvents(participant, selectedEvent)
      .then(data => { 
        paymentStatus = data;
      })

    return (
        <IonButton color={paymentStatus}>Button<IonButton>
    );

});

我尝试过使用 UseState,它在某种程度上可以工作,但我需要它在地图中工作,但我不能在 React Hook 中使用 useState。

编辑: 我已经尝试过异步/等待,但是当我这样做时出现以下错误: 错误:对象作为 React 子级无效(找到:[object Promise])。如果您打算渲染一组子项,请改用数组。

编辑:

这里是 fetchSelectedPaymentEvents() 的代码:

function fetchSelectedPaymentEvents(participant_id: any, event_id: any) {

        return axios({
            url: "URL",
            method: "POST",
            data: {
                "participant_id": participant_id,
                "payment_event_id": event_id
            }
        }).then(response => {
            var data = response.data["payment_records"]

            if (data === undefined || data.length == 0) {
                return "danger"
            }

            return "success"
        })

    }

顺便说一句,返回“danger”或“success”的目的不是准确地打印文本,而是更多地用于设置 Ionic 元素的样式。如果我的代码过于误导,请致歉。我进行了编辑以使其更接近我的实际需要。

【问题讨论】:

    标签: javascript reactjs ionic-framework


    【解决方案1】:

    我还认为您的组件的整体结构很容易出错。以下是我将如何尝试做你打算做的事情:

    const Component = () => {
      const participants = // whereever you get participants from;
      return (
        <ul>
          {participants.map(participant => {
              return <Participant participant={participant} />
            })
          }
        </ul>
      )
    }
    
    const Participant = ({ participant }) => {
      const [paymentStatus, setPaymentStatus] = useState("//initialState?");
    
      useEffect(() => {
        fetchSelectedPaymentEvents(participant, selectedEvent) // dont where selectedEvent comes from?
          .then(data => { 
            setPaymentStatus(data);
          })
      }, [participant]}
    
      return (
        <li>
          {paymentStatus}
        </li>
      )
    }
    

    希望这能让你的组件结构更容易一些

    【讨论】:

    • 谢谢。这绝对看起来是正确的方法,但我仍然收到此错误:对象作为 React 子项无效(找到:[object Promise])。如果您打算渲染一组子项,请改用数组。
    • 是的,我也看到了。在我必须修复它的大多数尝试中,您的函数总是返回 axios 对象或承诺。我认为使用 fetch 可能更直观,您尝试过 fetch 吗?它是原生的,因此对我来说是一个更好的选择
    • 好的,我设法解决了这个结构的问题,即使是使用 axios。有一个我没有删除的杂散异步,我不得不改变一些东西。谢谢!
    【解决方案2】:

    当您调用 fetchSelectedPaymentEvents 之类的 Promise 并使用 .then 语法时,您正在同步运行 fetchSelectedPaymentEvents 而不是异步。因此,您的 return 语句在 .then 之前被调用。

    你必须使用异步等待语法来解决这个问题:

    participants.map(async participant => {
        const paymentStatus = await fetchSelectedPaymentEvents(participant, selectedEvent);
    
        return (
            <IonText>{paymentStatus}<IonText>
        );
    });
    

    【讨论】:

    • 我已经尝试过了,但出现以下错误:错误:对象作为 React 子对象无效(找到:[object Promise])。如果您打算渲染一组子项,请改用数组。
    • 当您将数据放入 .then(data => ???) 时,它的外观如何。你能告诉我fetchSelectedPaymenEvents的代码吗?也许它不是一个承诺
    • 我已经编辑了我的代码以显示 fetchSelectedPaymentEvents 的代码。
    【解决方案3】:

    这是一种行之有效的方法,它看起来与您的有点不同,因为我是按照自己的方式做的,但我希望这会有所帮助。使用 Promise 并将它们传递下去以及弄清楚何时何地异步和等待时会令人困惑,尤其是使用 React 钩子时。我建议尽可能多地为您的状态逻辑和流程使用钩子,否则您的代码很容易出错。

    const fetchSelectedPaymentEvents = async (participant_id, event_id) => {
      try {
        const response = await axios({
          url: "URL",
          method: "POST",
          data: {
            participant_id: participant_id,
            payment_event_id: event_id
          }
        });
        var data = response.data["payment_records"];
        if (data === undefined || data.length == 0) {
          return "danger";
        }
        return "success";
      } catch (error) {
        return "failed";
      }
    };
    
    const App = () => {
      const [status, setStatus] = useState("pending");
    
      useEffect(() => {
        fetchSelectedPaymentEvents().then(data => setStatus(data));
      }, []);
    
      return <div className="App">{status}</div>;
    };
    

    【讨论】:

      【解决方案4】:
      Promise.all(participants.map(participant => {
      
          var paymentStatus = false;
          fetchSelectedPaymentEvents(participant, selectedEvent)
            .then(data => { 
              paymentStatus = data;
            })
      
          return (
              <IonText>{paymentStatus}<IonText>
          );
      
      }));
      

      尝试使用 promise.all() 包装您的 map 函数,因为您充当 this 的参数

      【讨论】:

      • 嗯 promise.all 似乎不存在?我也尝试过promises.all,但我收到错误“类型'typeof promises'上不存在属性'all'”。是因为我的 react 版本还是什么?
      • 你有没有在 Promise.all 中用大写 P 尝试过并等待这个
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-09
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2016-02-28
      相关资源
      最近更新 更多