我的 React-Redux 代码在之前的函数完成之前运行函数

Posted

技术标签:

【中文标题】我的 React-Redux 代码在之前的函数完成之前运行函数【英文标题】:My React-Redux Code is Running Functions Before the Previous Functions can Finish 【发布时间】: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 呢? 【参考方案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>

【讨论】:

以上是关于我的 React-Redux 代码在之前的函数完成之前运行函数的主要内容,如果未能解决你的问题,请参考以下文章

React-Redux-实现原理

react-redux s-s-r 异步 api 调用未按预期工作

如何在 react-redux 中调用页面刷新的函数?

使用通过 react、redux 和 react-redux 完成的组件以及在 react 应用程序中使用 webpack 构建时出错

我的 react-redux 项目中的 css 来自哪里

强烈键入 react-redux 与 typescript 连接