【问题标题】:Export the result of async function in React在 React 中导出异步函数的结果
【发布时间】:2018-08-23 07:35:08
【问题描述】:

我正在使用 .NET Core 构建一个 React 应用程序,并将一些常量值放入 appsettings.json 文件(不敏感)并将这些值公开为 API 控制器。我的想法是将 API 调用放在 .js 文件中并将值公开为常量,以便它们在所有其他 .js 文件中可用。

我有以下几点:

var y = "foo";

function successCallback(resp) {
    y = resp;
    console.log(y); //shows expected value
}

async function readConfig() {
    fetch('api/ClientConfiguration')
        .then(response => {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error('error...')
            }
        })
        .then(responseJson => {
            successCallback(responseJson.apiUrl);
        });
}

readConfig();

console.log(y); //shows "foo"

export const clientConfig = {
    apiUrl: y
};  

我了解 fetch 的异步特性使得 const clientConfig 中的属性始终具有“foo”值。有没有办法导出我想要的值(使用这种或其他方法)?谢谢。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    这是this problem 的一个特例。

    以后可以分配:

    function successCallback(resp) {
        clientConfig.apiUrl = resp;
    }
    ...
    export const clientConfig = {
        apiUrl: null
    };  
    

    不应该这样做;在其他模块中使用模块导入时,结果可能不存在,并且无法跟踪它何时出现。

    正确的方法是导出一个promise:

    export const clientConfig = fetch('api/ClientConfiguration')
    .then(response => {
        if (response.ok) {
            return response.json();
        } else {
            throw new Error('error...')
        }
    })
    .then(responseJson => {
        return { apiUrl: responseJson.apiUrl };
    });
    

    【讨论】:

    • 不客气。是的,它原本应该是一个承诺。您可以在父组件中解开一个承诺,作为对象道具传递给子组件,请参阅另一个答案以获得一些灵感。
    【解决方案2】:

    看起来没有一种简单或优雅的方法可以做到这一点,事物的异步性质也是如此。我的做法是创建一个执行获取的组件,然后让该组件在完成后将值传递给子级。

    这是一个粗略的例子。您可以使用context 使其更灵活,这将允许您将值更无缝地传递到树的下方,或者render props 这将允许您将此处的App 替换为任何其他组件。有很多方法可以做到这一点

    class ClientConfigProvider extends React.Component {
      state = {
        response: null,
        error: null,
      }
    
      componentDidMount() {
        fetch("api/ClientConfiguration")
          .then((response) => {
            if (response.ok) {
              return response.json()
            } else {
              this.setState({ error: "oops" })
            }
          })
          .then((response) => {
            this.setState({ response })
          })
      }
    
      render() {
        if (error) {
          return <div>Error while fetching config: {this.state.error}</div>
        }
        if (response) {
          return <App apiUrl={this.state.response.apiUrl} />
        }
        return <div>Loading...</div>
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-08-01
      • 2023-03-03
      • 2018-10-04
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多