我正在尝试使用模块 redux、react-redux 来切换应用程序中显示的当前视图,但调度我的 action creator 不会调用 reducer。我已经使用控制台消息显示在初始化期间调用了相应的 reducer,在调度时调用了 action creator,但是 action creator 没有触发 reducer。
客户端/src/App.js
import React, { Component } from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider, connect } from 'react-redux';
// actions
const SET_VIEW = 'SET_VIEW';
const setView = (view) => {
console.log(view);
return { type: SET_VIEW, view };
};
// views
const HOME_VIEW = 'HOME';
const OTHER_VIEW = 'OTHER';
//reducers
const initialState = {
view: HOME_VIEW,
};
const viewReducer = function (state, action) {
console.log(JSON.stringify(action));
if (action.type === SET_VIEW) {
if (action.view === HOME_VIEW) {
return HOME_VIEW;
}
if (action.view === OTHER_VIEW) {
return OTHER_VIEW;
}
}
return HOME_VIEW;
};
const rootReducer = combineReducers({
view: viewReducer,
});
// selectors
const getView = (state) => state.view;
//store
const store = createStore(rootReducer, initialState);
function Main({ view }) {
return (
<div
style={{
width: '250px',
display: 'block',
margin: 'auto',
borderColor: 'black',
borderStyle: 'solid',
borderWidth: '1px',
}}
>
{view === HOME_VIEW && <HomeViewConnected />}
{view === OTHER_VIEW && <OtherView />}
</div>
);
}
const MainConnected = connect(
(state) => ({
view: getView(state),
}),
null
)(Main);
function HomeView() {
return (
<div>
<button onClick={() => setView(OTHER_VIEW)}>View Other</button>
</div>
);
}
const HomeViewConnected = connect(null, (dispatch) => ({
setView: (value) => dispatch(setView(value)),
}))(HomeView);
class OtherView extends React.Component {
render() {
return (
<div>
<p>Other</p>
</div>
);
}
}
class App extends Component {
render() {
return (
<Provider store={store}>
<MainConnected />
</Provider>
);
}
}
export default App;
我的控制台显示,当页面加载时,reducer 通过 INIT 操作被调用了三次。按下“其他”按钮后,将打印来自 action creator 的消息,但不会打印来自 reducer 的消息。
我试过重启开发服务器。 类似文章的提问者似乎经常滥用 dispatch。我认为我使用 dispatch 是正确的,因为我比较了 Tsonev 精彩的“React in Patterns”中的 redux 代码。 https://github.com/krasimir/react-in-patterns/blob/master/code/redux/src/app.jsx
编辑以修复糟糕的格式。
Randy Casburn 的观察解决了我的问题。
我不知道为什么 connect() 不起作用,因为它应该用于 react-redux 8.x,但是切换到推荐的钩子 API 使我的动作创建器 setView 正确触发了减速器 viewReducer。 https://react-redux.js.org/api/connect
具体来说,重新定义 HomeViewConnected 使其工作。
const HomeViewConnected = () => {
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(setView(OTHER_VIEW))} >View Other</button>
</div>
);
}
谢谢兰迪!