使用反应16.8.2,hooks API。
Redux初始状态:
const initialState = {
name: one,
count: 1,
}
零件:
function CompTwo(props) {
useActiveCount(setActiveCount, 2);
useEffect(() => {
// activeCount is still 1
if(activeCount === 2) {
setActiveName('two')
}
});
}
const mapStateToProps = state => ({
activeCount: state.count,
});
const mapDispatchToProps = dispatch => ({
setActiveCount: count => dispatch(updateActiveCount(count)),
setActiveName: name => dispatch(updateActiveName(name),
});
export default connect(mapStateToProps, mapDispatchToProps)(CompTwo);
useActiveCount:
const useActiveCount = function (setActiveCount, count) {
useEffect(() => {
setActiveCount(count);
})
}
在CompTwo
,如果我在设置活动名称useActiveCount(setActiveCount, 2);
之前设置计数setActivePage('two')
,我不应该在2
道具中获得新值activeCount
吗?
它确实将activeCount
设置为2,当我在dev-tool控制台中检查redux logger中的状态值时,但是在useEffect
的CompTwo
代码中,我仍然得到activeCount
的旧值,即1
。
为什么会这样?
你需要将activeCount传递给useEffect
钩子,否则一旦动作完全完成就不会重新触发钩子。
function CompTwo({ activeCount, setActiveCount, setActiveName }) {
useActiveCount(setActiveCount, 2);
useEffect(() => {
if(activeCount === 2) {
setActiveName('two');
}
}, [activeCount]);
}
可运行的例子:
// Custom hook
const useActiveCount = (setActiveCount, count) => {
React.useEffect(
() => {
setActiveCount(count);
}, [count]
);
};
// Redux types
const SET_ACTIVE_COUNT = "SET_ACTIVE_COUNT";
const SET_ACTIVE_NAME = "SET_ACTIVE_NAME";
// Redux actions
const updateActiveCount = count => ({
type: SET_ACTIVE_COUNT,
count,
});
const updateActiveName = name => ({
type: SET_ACTIVE_NAME,
name,
});
// Redux Reducer
const reducer = (state = { count: 0 }, action) => {
switch (action.type) {
case SET_ACTIVE_COUNT:
return {
...state,
count: action.count
};
case SET_ACTIVE_NAME:
return {
...state,
name: action.name
};
default:
return state;
}
};
const store = Redux.createStore(reducer);
// Comp 2
function CompTwo({ activeCount, activeName, setActiveCount, setActiveName }) {
useActiveCount(setActiveCount, 2);
React.useEffect(() => {
console.log(activeCount);
if (activeCount === 2) {
console.log('hit');
setActiveName('Two');
}
}, [activeCount]);
return (
<React.Fragment>
<h5>Count: {activeCount}</h5>
<h5>Name: {activeName}</h5>
</React.Fragment>
);
}
const mapStateToProps = state => ({
activeCount: state.count,
activeName: state.name,
});
const mapDispatchToProps = dispatch => ({
setActiveCount: count => dispatch(updateActiveCount(count)),
setActiveName: name => dispatch(updateActiveName(name)),
});
const Comp = ReactRedux.connect(
mapStateToProps,
mapDispatchToProps
)(CompTwo);
// App
const App = () => (
<ReactRedux.Provider store={store}>
<Comp />
</ReactRedux.Provider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/6.0.1/react-redux.min.js"></script>
<div id="root"></div>