动作未调度

时间:2019-04-16 16:53:15

标签: reactjs redux react-redux redux-thunk

当我运行动作创建者来创建自己的thunk时,它不会运行调度功能。

为了进行测试,我在根组件的render方法中放置了一个按钮,根组件已连接好(删除了多余的东西):

import { loadAndSetCurrentUser } from '../Actions/SedFF';
import { setSysMenuExpand, setNavMenuExpand, setLoginDialogVisibility } from '../Actions/UI';

render() {
    return (
        <button onClick={() => 
            loadAndSetCurrentUser("username@email.com")}>LASCU</button>
    )
}

const mapStateToProps = function (state) {
    return {
        UI: state.UI,
        sedff: state.SedFF,
    }
}

const mapDispatchToProps = {
    loadAndSetCurrentUser,
}


export default withStyles(styles, { withTheme: true })(withRouter(connect(mapStateToProps, mapDispatchToProps)(WebFF)));

“我的动作创建者”文件如下所示:

export function loadAndSetCurrentUser(username) {
    console.log("LASCU: " + username);
    return (dispatch, getState) => {
        console.log("in dispatch");
        dispatch(this.requestingUserData(username)); 

        const user = getState().Users[username];
        if (user) {
            // if already in store, just change the current username  
            //FUTURE: check date against user mod date in database
            dispatch(setCurrentUsername(username));
            dispatch(userDataLoadComplete());
        } else {
            // user not in store, need to check database //TODO:
            fetch('https://jsonplaceholder.typicode.com/users?username=Bret')
                .then(response => response.json())
                // .then(json => delay(3000, json))
                .then(json=> dispatch(ingestUserData(json)))
                .then(() => dispatch(userDataLoadComplete()));
        }
    }
}

export function requestingUserData(username) {
    console.log("RUD");
    return { type: REQUESTING_USER_DATA, username };
}

export function setCurrentUsername(username) {
    return { type: SET_CURRENT_USERNAME, username }
}

export function ingestUserData(userData) {
    return (dispatch) =>
        {
            console.log("IUD");
            console.log(userData);
            dispatch({ type: SET_USER_DATA, userData })
        }
}

export function userDataLoadComplete() {
    return { type: USER_DATA_LOAD_COMPLETE };
}

我的减速器是骨料,看起来像这样:

export function SedFF(state = initialSedFFState, action) {
    let newState = _.cloneDeep(state);
    switch (action.type) {
        case SET_CURRENT_USERNAME:
            newState.currentUsername = action.username
            return newState;
        case LOAD_USER_DATA:
            //TODO: 
             return newState;
        case REQUESTING_USER_DATA:
            newState.isFetchingUserData = true;
            return newState;
        case RECEIVED_USER_DATA:
            //TODO:
            newState.isFetchingUserData = false;
            return newState
        case USER_DATA_LOAD_COMPLETE:
            //TODO:
            newState.isFetchingUserData = false;
            return newState

... etc, etc...

        default:
            return state
    }
}

当我按下LASCU按钮时,将得到以下输出:LASCU: username@email.com来自我的动作创建者(在上面的动作创建者文件的第二行中有注明)。我在动作创建者文件的第4行上没有得到in dispatch输出。我没有触发任何动作。

我不确定为什么不调度。

我会注意到,在另一个组件(子组件)上,我可以启动整个组件,但是我找不到任何区别。唯一真正的区别似乎是我在出口线路中没有路由器: export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(SystemMenu));

对于它的价值,我的重磅中间件连接到App.js(我的根组件的父级),就像这样:

const store = createStore(
    RootReducer, 
    initialState, 
    composeEnhancer(applyMiddleware(thunk))
);

class App extends React.Component {

    render() {
        return (
            <Provider store={store}>
                <CssBaseline />
                <BrowserRouter>
                    <WebFF />
                </BrowserRouter>
            </Provider>
        );
    }
}


export default withStyles(styles, { withTheme: true })(App);

有什么想法吗?帮助吗?

2 个答案:

答案 0 :(得分:1)

看问题中给出的render方法,问题似乎在于您正在调用原始导入的函数,而不是props中的绑定函数。换句话说,更改为this.props.loadAndSetCurrentUser()应该可以正常工作。请注意,you shouldn't be importing the store directly into a component file

有关更多详细信息,请参见React-Redux usage guide docs page on "Dispatching Actions with mapDispatch"

答案 1 :(得分:0)

您仍然必须发送 Thunk动作,否则它将仅返回该动作,而不对其执行任何操作。

render() {
    return (
        <button onClick={() => 
            store.dispatch(loadAndSetCurrentUser("username@email.com"))
        }>LASCU</button>
    )
}

所以,基本上您的操作类似于:

const action = function (username) { return function () { alert(username); }}
console.log(action('123')); // This will just log `function () { alert(username); }`, without actually running the alert()

因此,即使您调用action('123'),它也只会返回仍必须以某种方式调用的函数。对于Thunks,必须分派返回的函数。