【问题标题】:How to Run an Async Action Creator inside an Async Redux Thunk Action Creator?如何在 Async Redux Thunk Action Creator 中运行 Async Action Creator?
【发布时间】:2020-08-17 14:08:45
【问题描述】:

我正在尝试找出在 Async Redux Thunk Action Creator 中运行 Async Action Creator 的正确实现。以下哪个方法是正确的?

方法一:

export const loginUser = () => async(dispatch) => {        
    try {
        user = await LoginManager.logInWithPermissions(['public_profile', 'email']);                              
        dispatch({type: LOGIN, payload: user});
        dispatch({type:SAVE_USER_TO_DEVICE, payload:saveUserToDevice(user)});                              
    } catch (error) {
        console.log(error);
    }
}

export const saveUserToDevice = async(user)=> {        
    try {
        //saveUserToDeviceStatus returns true if successful, otherwise returns an object
        const saveUserToDeviceStatus = await Keychain.setGenericPassword('user', JSON.stringify(user)); 
        return (saveUserToDeviceStatus? true: false);
    } catch (error) {
        console.log(error);
    }    
}

方法二: saveUserToDevice 自行调度

export const loginUser = () => async(dispatch) => {        
    try {                     
        user = await LoginManager.logInWithPermissions(['public_profile', 'email']);                      
        dispatch({type: LOGIN, payload: user});
        saveUserToDevice(user);
    } catch (error) {
        console.log(error);
    }
}

export const saveUserToDevice = (user) => async(dispatch) => {        
    try {
        //saveUserToDeviceStatus returns true if successful, otherwise returns an object
        const saveUserToDeviceStatus = await Keychain.setGenericPassword('user', JSON.stringify(user)); 
        saveUserToDeviceStatus = saveUserToDeviceStatus? true: false;
        dispatch({type: SAVE_USER_TO_DEVICE, payload: saveUserToDeviceStatus});
    } catch (error) {
        console.log(error);
    }    
}

方法三: saveUserToDevice 返回动作对象

export const loginUser = () => async(dispatch) => {        
    try {                     
        user = await LoginManager.logInWithPermissions(['public_profile', 'email']);                      
        dispatch({type: LOGIN, payload: user});
        const saveUserToDeviceAction = await saveUserToDevice(user);
        dispatch(saveUserToDeviceAction);
    } catch (error) {
        console.log(error);
    }
}

export const saveUserToDevice = async(user) => {        
    try {
        //saveUserToDeviceStatus returns true if successful, otherwise returns an object
        const saveUserToDeviceStatus = await Keychain.setGenericPassword('user', JSON.stringify(user)); 
        saveUserToDeviceStatus = saveUserToDeviceStatus? true: false;
       return {type: SAVE_USER_TO_DEVICE, payload: saveUserToDeviceStatus};
    } catch (error) {
        console.log(error);
    }    
}

方法四: saveUserToDevice 返回布尔值,在 loginUser 内部触发 d​​ispatch

export const loginUser = () => async(dispatch) => {        
    try {                     
        user = await LoginManager.logInWithPermissions(['public_profile', 'email']);                      
        dispatch({type: LOGIN, payload: user});
        const saveUserToDeviceAction = await saveUserToDevice(user);
        dispatch({type: SAVE_USER_TO_DEVICE, payload: saveUserToDeviceAction});
    } catch (error) {
        console.log(error);
    }
}

export const saveUserToDevice = async(user) => {        
    try {
        //saveUserToDeviceStatus returns true if successful, otherwise returns an object
        const saveUserToDeviceStatus = await Keychain.setGenericPassword('user', JSON.stringify(user)); 
        saveUserToDeviceStatus = saveUserToDeviceStatus? true: false;
       return saveUserToDeviceStatus;
    } catch (error) {
        console.log(error);
    }    
}

【问题讨论】:

    标签: reactjs react-native redux react-redux redux-thunk


    【解决方案1】:

    saveUserToDevice 是一个动作,你实际上需要 dispatch 动作而不是调用它。

    正确的做法是

    dispatch(saveUserToDevice(user));
    

    saveUserToDevice 也必须将操作发送为

    dispatch({type: SAVE_USER_TO_DEVICE, payload: saveUserToDeviceStatus});
    

    完整代码

    export const loginUser = () => async(dispatch) => {        
        try {                     
            user = await LoginManager.logInWithPermissions(['public_profile', 'email']);                      
            dispatch({type: LOGIN, payload: user});
            dispatch(saveUserToDevice(user));
        } catch (error) {
            console.log(error);
        }
    }
    
    export const saveUserToDevice = (user) => async(dispatch) => {        
        try {
            //saveUserToDeviceStatus returns true if successful, otherwise returns an object
            const saveUserToDeviceStatus = await Keychain.setGenericPassword('user', JSON.stringify(user)); 
            saveUserToDeviceStatus = saveUserToDeviceStatus? true: false;
            dispatch({type: SAVE_USER_TO_DEVICE, payload: saveUserToDeviceStatus});
        } catch (error) {
            console.log(error);
        }    
    }
    

    根据您的第一个解决方案,如果您等待 saveUserToDevice(result)} 之类的是否可行

    export const loginUser = () => async(dispatch) => {        
        try {
            user = await LoginManager.logInWithPermissions(['public_profile', 'email']);                              
            dispatch({type: LOGIN, payload: user});
            const data = await saveUserToDevice(result);
            dispatch({type:SAVE_USER_TO_DEVICE, payload: data});                              
        } catch (error) {
            console.log(error);
        }
    }
    
    export const saveUserToDevice = async(user)=> {        
        try {
            //saveUserToDeviceStatus returns true if successful, otherwise returns an object
            const saveUserToDeviceStatus = await Keychain.setGenericPassword('user', JSON.stringify(user)); 
            return (saveUserToDeviceStatus? true: false);
        } catch (error) {
            console.log(error);
        }    
    }
    

    然而,在这两种方法中,将saveUserToDevice 作为一个动作并调度它的方法更简洁

    【讨论】:

    • 对不起,我不太明白。在方法 2 中, saveUserToDevice() 内部有一个调度。我应该使用 loginUser() 作为 thunk 动作创建者和 saveUserToDevice() 作为正常动作创建者吗?还是让他们两个都成为动作创建者并将 saveUserToDevice() 放入 loginUser() 然后让他们使用自己的调度函数调度?
    • 对不起,我刚才为方法 2 输入了错误的操作类型,它应该是类型:SAVE_USER_TO_DEVICE
    • 我添加了方法3和4,请查看您推荐的方法。
    • 如果按照将saveUserToDevice设为action的方式,是否需要分派两次?调度(保存用户到设备(用户)); dispatch({type: SAVE_USER_TO_DEVICE, payload: saveUserToDeviceStatus});
    • @Kevin 这里的正确方法是将它们都作为动作创建者,这是我方法中的第一种方法,因为它使您可以更灵活地添加更多逻辑并从 saveUserToDevice 中更新状态。还因为将其编写为 thunk 动作创建者,您也可以将其用作独立动作
    猜你喜欢
    • 1970-01-01
    • 2016-12-11
    • 2020-02-03
    • 2018-09-27
    • 2020-02-05
    • 2023-04-01
    • 2019-04-25
    • 1970-01-01
    • 2020-03-09
    相关资源
    最近更新 更多