Redux - 如何调用一个动作并等待它解决

Posted

技术标签:

【中文标题】Redux - 如何调用一个动作并等待它解决【英文标题】:Redux - how to call an action and wait until it is resolved 【发布时间】: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 响应来知道客户端是有效还是无效。也就是我需要解决这个动作,然后验证客户端是有效还是无效。

【问题讨论】:

【参考方案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));

【讨论】:

以上是关于Redux - 如何调用一个动作并等待它解决的主要内容,如果未能解决你的问题,请参考以下文章

Redux thunk:如何等待异步操作的完成

在调用另一个动作创建者之前等待动作创建者完成 - Redux thunk

Redux-thunk 调度一个动作并等待重新渲染

如何在 redux-saga 中等待另一个动作

如何等待一个动作完成?

另一个组件如何在 react/redux 中监听另一个组件的动作?