【问题标题】:My React-Redux Code is Running Functions Before the Previous Functions can Finish我的 React-Redux 代码在之前的函数完成之前运行函数
【发布时间】:2021-03-31 16:50:06
【问题描述】:

如何编写这些函数,以便在 if 语句开始之前完成分派?目前,if 语句在调度之前启动 console.log()'ing 甚至可以保存数据。

  const doStuff = () => {
    dispatch(getStuff()); // WAIT FOR ME TO COMPLETE BEFORE MOVING ON!!!
    
    if (stuff) {   //stuff is retreived from global state
      console.log("stuff available") //I WAITED FOR THE DISPATCH!
    }

    if (!stuff) {   //stuff is retreived from global state
      console.log("no stuff") //I WAITED FOR THE DISPATCH!
    }
  };

export const getStuff = () => { \\WAIT FOR ME TO SAVE STUFF!!!
  return (dispatch) => {
      axios.get(`/stuff`).then((response) => {
      dispatch({
        type: SAVE_STUFF_TO_STATE, //stuff is saved to global state
        payload: response.data, //stuff
      });
      })
    } catch (err) {
      console.log("stuff issue")
    }
  };
};

【问题讨论】:

  • 东西是怎么“塞”起来的?
  • @MetallimaX 东西通过reducer保存到状态。
  • 你如何检索状态?
  • @MetallimaX 使用 useSelector 从状态中检索东西。
  • 你为什么不使用 useEffect 呢?

标签: javascript reactjs asynchronous redux async-await


【解决方案1】:

你可以从函数中返回promise,你可以尝试使用https://github.com/reduxjs/redux-thunk

enter code hereexport const getStuff = () => { \\WAIT FOR ME TO SAVE STUFF!!!
 return (dispatch) => {
    axios.get(`/stuff`).then((response) => {
      return Promise.resolve(
         // the actions to be dispatched goes here
      );
    })
  } catch (err) {
     console.log("stuff issue")
  }
 };
};

并等待它执行,

 const doStuff = () => {
    dispatch(getStuff()).then(()=> { // WAIT FOR ME TO COMPLETE BEFORE MOVING ON!!!

      if (stuff) {   //stuff is retreived from global state
       console.log("stuff available") //I WAITED FOR THE DISPATCH!
      }

      if (!stuff) {   //stuff is retreived from global state
       console.log("no stuff") //I WAITED FOR THE DISPATCH!
      }
   });
 };

一般来说,如果您想在调度中链接某些活动(根据您的示例),您的操作需要返回一个 Promise

【讨论】:

  • 我在问这个问题之前试过这个,但是为了好玩我又试了一次,它不起作用。我收到一个错误:无法读取未定义的属性“then”。我读到了这个,因为调度函数不返回任何东西,所以它们不能有 .then()。
  • 你需要从getStuff返回promise:return axios.get(/stuff).then
  • @HMR 我只是尝试将返回添加到 axios、Promise 和单独调度,但都没有奏效。您指定的那个通过以某种方式停止承诺中的调度函数来破坏代码。其他人提出了相同的原始错误。
  • @user67 我已经添加了一个工作示例,如果你不能让它工作,那么请提供一个沙箱来演示这个问题。
  • @HMR 好的,谢谢,我目前正在查看并理解您的示例。
【解决方案2】:

您的 Promise 创建函数需要返回一个 Promise,而您的 thunk 操作需要返回该 Promise:

const { Provider, useDispatch, useSelector } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;

const initialState = {
  status: 'initial',
};
//action types
const ONE = 'ONE';
const TWO = 'TWO';
//action creators
const later = (value, time = 2000) =>
  new Promise((resolve) =>
    setTimeout(() => resolve(value), time)
  );
const one = () => (dispatch) =>
  //return the promise here
  later()
    .then(() => dispatch({ type: ONE }))
    .then(() => later('the value one resolves with'));
const two = () => ({ type: TWO });
const reducer = (state, { type, payload }) => {
  if (type === ONE) return { ...state, status: 'one' };
  if (type === TWO) return { ...state, status: 'two' };
  return state;
};
//selectors
const selectStatus = (state) => state.status;
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancers(
    applyMiddleware(
      ({ dispatch, getState }) => (next) => (action) =>
        //basic thunk implementation
        typeof action === 'function'
          ? action(dispatch, getState)
          : next(action)
    )
  )
);
const App = () => {
  const dispatch = useDispatch();
  React.useEffect(() => {
    one()(dispatch).then((oneResolve) => {
      console.log('one resolved with:', oneResolve);
      dispatch(two());
    });
  }, [dispatch]);
  const status = useSelector(selectStatus);
  return <h1>Status:{status}</h1>;
};

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  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>

【讨论】:

    猜你喜欢
    • 2015-06-29
    • 2018-05-27
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多