当我运行动作创建者来创建自己的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);
有什么想法吗?帮助吗?
答案 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,必须分派返回的函数。