如何使用await在非异步中调用异步方法?

时间:2021-01-20 14:35:45

标签: reactjs typescript react-redux

我正在尝试通过从后端获取数据来设置 redux 中的初始状态。但我不明白如何使用异步等待获取方法来更新获取数据的初始状态。我尝试在 createReduxStore 中调用异步方法,但无法解决承诺。请帮忙!附上代码供参考。

Index.tsx

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import createReduxStore from "./redux/store/store";
import initialState from "./redux/store/initialState";
import { IApplicationState } from "./models/applicationState";

const defaultState: IApplicationState = initialState;
const store = createReduxStore(defaultState, true);

ReactDOM.render(
    <Provider store={store}>
        <App/>
    </Provider>
    , document.getElementById("rootdiv"));

Store.ts

import { applyMiddleware, createStore, Store } from "redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";
import { IApplicationState } from "../../models/applicationState";
import { mergeInitialState } from "../middleware/fetchData";
import { Env } from "../../common/environment";

export default function createReduxStore(
    initialState?: IApplicationState,
    useLocalStorage: boolean = false): Store {
    const paths: string[] = ["appSettings", "connections", "recentProjects", "prebuiltSettings"];

     data = this.getData();
     initialstate["appSettings"]=data;
    let middlewares = [thunk];

    if (useLocalStorage) {
        const localStorage = require("../middleware/localStorage");
        const storage = localStorage.createLocalStorage({paths});
        middlewares = [
            ...middlewares,
            storage,
        ];
    }

    return createStore(
        rootReducer,
        useLocalStorage ? mergeInitialState(initialState, paths) : initialState,
        applyMiddleware(...middlewares),
    );
}

async function getData(){
const request =  await fetch("url",{
method:'GET',
headers:{
'Accept':'application/json',
'Content-Type':'application/json',
}
});
if(request.ok){
 var response = await request.json();
}
return response;
}

详细代码请refer to

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

您的 createReduxStore 函数可以返回解析为存储的承诺,您可以在 AsyncProvider 组件中使用该承诺,只要存储未解析,该组件就会返回加载:

const { Provider, useSelector } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
const someAsync = () =>
  new Promise((r) => setTimeout(() => r([1, 2, 3]), 2000));
const reducer = (state) => state;
function createReduxStore() {
  const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
  return someAsync().then((asyncData) =>
    createStore(
      reducer,
     {asyncData},
      composeEnhancers(
        applyMiddleware(() => (next) => (action) =>
          next(action)
        )
      )
    )
  );
}
const asyncStore = createReduxStore();
const AsyncProvider = ({ children }) => {
  const [store, setStore] = React.useState(false);
  //effect that will set local store state with
  //  redux store when asyncStore resolves
  React.useEffect(() => {
    asyncStore.then((store) => setStore(store));
    //this is missing catch to be used if something goes wrong
    //  you may want to solve that in your createReduxStore function
    //  if something goes wrong then provide the error in initial state
  }, []);
  //will only render provider when store is resolved
  return store ? (
    <Provider store={store}>{children}</Provider>
  ) : (
    'state is loading'
  );
};
const App = () => {
  const reduxState = useSelector((state) => state);
  return (
    <div>
      <h1>In App, state is:</h1>
      <pre>{JSON.stringify(reduxState, undefined, 2)}</pre>
    </div>
  );
};

ReactDOM.render(
  <AsyncProvider>
    <App />
  </AsyncProvider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>