【问题标题】:How to use a promised function in a react app如何在 React 应用程序中使用承诺的功能
【发布时间】:2020-06-12 07:05:10
【问题描述】:

我正在尝试在 React 网络应用程序中实现 Bullet train API。根据他们的node client documentation,我设置了以下功能:

export const isFeatureEnabled = async (nameOfTheFeature) => {
    return new Promise((resolve) => {

        bulletTrain.init({
            environmentID: BULLET_TRAIN_ENV_ID
        });

        bulletTrain.hasFeature(nameOfTheFeature)
            .then((featureFlag) => {
                if (featureFlag[nameOfTheFeature].enabled) {
                    resolve(true);
                }
            })
            .catch(err => resolve(false));
    });
}

这在像这样的常规组件中被调用:

render() {
  return (<div>{await isFeatureEnabled('feature1') && <p>feature1 is enabled</p>}</div>)
};

抛出这个:

解析错误:不能在异步函数之外使用关键字 'await'

如果我们添加 async 关键字,并带有适当的返回语句:

async render() {
  return (<div>{await isFeatureEnabled('feature1') && <p>feature1 is enabled</p>}</div>)
};

然后它抛出:

你的渲染方法应该有return语句

那么在 react 应用程序中使用这个承诺的功能的正确方法是什么?

【问题讨论】:

    标签: node.js reactjs promise async-await


    【解决方案1】:

    在挂载期间(在您希望之前/之后)在异步函数中调用函数 isFeatureEnabled

    示例 -

    
    export const isFeatureEnabled = async (nameOfTheFeature) => {
        return new Promise((resolve) => {
    
            bulletTrain.init({
                environmentID: BULLET_TRAIN_ENV_ID
            });
    
            bulletTrain.hasFeature(nameOfTheFeature)
                .then((featureFlag) => {
                    if (featureFlag[nameOfTheFeature].enabled) {
                        resolve(true);
                    }
                })
                .catch(err => resolve(false));
        });
    }
    
    ...
    componentDidMount() {
      this.checEnabled();
    }
    ...
    const checkEnabled = async () => {
    
    const flag = await isFeatureEnabled('feature1');
    
    this.setState({f1enabled: flag});
    
    }
    ...
    render() {
      return (<div>{this.state.f1enabled ? <p>feature1 is enabled</p> : null}</div>)
    }
    

    如果 isFeatureEnabled 在同一个文件中,则将其保留在类组件之外,否则将其保留在另一个文件中并导出函数。

    【讨论】:

      【解决方案2】:

      我建议您不要在render 中使用await 关键字,而是使用componentDidMountconstructor 并使用状态对象来检查:

      constructor(props){
          super(props);
          this.state = { isFeatEnabled: false };
      }
      
      componentDidMount(){
          this.setState({isFeatEnabled:isFeatureEnabled('feature1')})
      }
      

      现在在渲染中:

      render() {
        return (<div>{this.state.isFeatEnabled && <p>feature1 is enabled</p>}</div>)
      };
      

      并从方法中删除async

      【讨论】:

      • 这看起来棒极了!我要试试这个。一旦它工作将更新:)
      【解决方案3】:

      你不能在那里使用promise,正确的方法:

      import React, { useEffect, useState } from 'react'
      import bulletTrain from '../somewhere'
      import BULLET_TRAIN_ENV_ID from '../somewhere'
      
      export default function featureComponent({ featureName }) {
        const [featureEnabled, setFeatureEnabled] = useState(false)
      
        useEffect(() => {
          bulletTrain.init({
            environmentID: BULLET_TRAIN_ENV_ID
          })
      
          bulletTrain
            .hasFeature(featureName)
            .then(featureFlag => {
              if (featureFlag[featureName].enabled) {
                setFeatureEnabled(true)
              }
            })
            .catch(err => setFeatureEnabled(false))
        }, [featureName])
      
        return <div>{featureEnabled && <p>{featureName} is enabled</p>}</div>
      }
      

      在下面追加isFeatureEnabled函数重用答案:

      import React, { useEffect, useState } from 'react'
      import isFeatureEnabled from '../somewhere'
      
      export default function featureComponent({ featureName }) {
        const [featureEnabled, setFeatureEnabled] = useState(false)
      
        useEffect(() => {
          const checkAndSetEnabled = async () => {
            const enabled = await isFeatureEnabled(featureName)
            setFeatureEnabled(enabled)
          }
          checkAndSetEnabled()
        }, [featureName])
      
        return <div>{featureEnabled && <p>{featureName} is enabled</p>}</div>
      }
      

      【讨论】:

      • 我想确保该函数保留在单独的实用程序文件中以便可以重复使用
      • Hooks 仍然可以满足您重用实用功能的需求。附加上面的解决方案。
      猜你喜欢
      • 2017-10-18
      • 2013-11-29
      • 1970-01-01
      • 2018-03-31
      • 2018-05-24
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      • 2020-12-14
      相关资源
      最近更新 更多