【问题标题】:Redux - how to call an action and wait until it is resolvedRedux - 如何调用一个动作并等待它解决
【发布时间】:2019-05-31 23:12:12
【问题描述】:

我正在使用 react native + redux + redux-thunk 我对 redux 和 react native 没有太多经验

我在我的组件中调用一个动作。

this.props.checkClient(cliente);

if(this.props.clienteIsValid){
   ...
}

在该操作中,需要几秒钟的时间调用一个 api。

export const checkClient = (cliente) => {
    return dispatch => {

        axios.get(`${API_HOST}/api/checkclient`, header).then(response => {

            dispatch({type: CHECK_CLIENT, payload: response.data }); //valid or invalid

        }).catch((error) => {  });

    }
}

我的问题是如何延迟操作的返回,直到 api 响应完成?我需要 api 响应来知道客户端是有效还是无效。也就是我需要解决这个动作,然后验证客户端是有效还是无效。

【问题讨论】:

    标签: reactjs react-native redux redux-thunk


    【解决方案1】:

    我不明白这个问题,但也许这会有所帮助

    export const checkClient = (cliente) => {
      return dispatch => {
        dispatch({type: CHECK_CLIENT_PENDING });
    
        axios.get(`${API_HOST}/api/checkclient`, header).then(response => {
    
            dispatch({type: CHECK_CLIENT, payload: response.data }); //valid or invalid
    
        }).catch((error) => {  });
    
       }
    }
    

    ...


     this.props.checkClient(cliente);
    
     if(this.props.clienteIsPending){
      ...
     }
    
     if(this.props.clienteIsValid){
      ...
     }
    

    【讨论】:

      【解决方案2】:

      你可以从action中返回一个promise,这样调用就变成了thenable

      // Action
      export const checkClient = (cliente) => {
          return dispatch => {
              // Return the promise
              return axios.get(...).then(res => {
                  ...
                  // Return something
                  return true;
              }).catch((error) => {  });
          }
      }
      
      
      class MyComponent extends React.Component {
      
          // Example
          componentDidMount() {
              this.props.checkClient(cliente)
                  .then(result => {
                      // The checkClient call is now done!
                      console.log(`success: ${result}`);
      
                      // Do something
                  })
          }
      }
      
      // Connect and bind the action creators
      export default connect(null, { checkClient })(MyComponent);
      

      这可能超出了问题的范围,但如果您愿意,可以使用 async await 而不是 then 来处理您的承诺:

      async componentDidMount() {
          try {
              const result = await this.props.checkClient(cliente);
              // The checkClient call is now done!
              console.log(`success: ${result}`)
      
              // Do something
          } catch (err) {
              ...
          }
      }
      

      这做同样的事情。

      【讨论】:

      • 我在结果中变得不确定。为什么它未定义@micnil
      • @micnil 你能告诉我如何使用反应钩子 useDispatch() 函数来完成这项工作吗?
      【解决方案3】:

      如果仍有混乱,我已经编写了完整的代码。 promise 应该适用于一系列异步 redux 操作调用

      操作

      export const buyBread = (args) => {
        return dispatch => {
          return new Promise((resolve, reject) => {
      
              dispatch({type: BUY_BREAD_LOADING });
              // or any other dispatch event
      
              // your long running function
             
              dispatch({type: BUY_BREAD_SUCCESS, data: 'I bought the bread'});
              // or any other dispatch event
      
              // finish the promise event
              resolve();
      
              // or reject it
              reject();
          
          });
      }
      
      export const eatBread = (args) => {
        return dispatch => {
          return new Promise((resolve, reject) => {
      
              dispatch({type: EAT_BREAD_LOADING });
              // or any other dispatch event
      
              // your long running function
             
              dispatch({type: EAT_BREAD_SUCCESS, data: 'I ate the bread'});
              // or any other dispatch event
      
              // finish the promise event
              resolve();
      
              // or reject it
              reject();
          
          });
      }
      

      减速器

      const initialState = {}
      export const actionReducer = (state = initialState, payload) => {
          switch (payload.type) {
              case BUY_BREAD_LOADING:
                 return { loading: true };
              case BUY_BREAD_SUCCESS:
                 return { loading: false, data: payload.data };
              case EAT_BREAD_LOADING:
                 return { loading: true };
              case EAT_BREAD_SUCCESS:
                 return { loading: false, data: payload.data };
      }
      

      组件类

      import React, {Component} from 'react';
      
      class MyComponent extends Component {
          render() {
              return (
                  <div>
                      <button onClick={()=>{
                          this.props.buyBread().then(result => 
                              this.props.eatBread();
                              // to get some value in result pass argument in resolve() function
                          );
                      }}>I am hungry. Feed me</button>
                  </div>
              );
          }
      }
      
      const mapStateToProps = (state) => ({
          actionReducer: state.actionReducer,
      });
      
      const actionCreators = {
          buyBread: buyBread,
          eatBread: eatBread
      };
      
      export default connect(mapStateToProps, actionCreators)(MyComponent));
      

      【讨论】:

        猜你喜欢
        • 2017-04-18
        • 2018-09-28
        • 2023-04-05
        • 2020-04-23
        • 2022-01-12
        • 1970-01-01
        • 2016-02-24
        • 2020-01-07
        • 2021-10-10
        相关资源
        最近更新 更多