这是来自的示例:https ://reactjs.org/docs/hooks-reference.html#usereducer
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
在此示例中,reducer
函数的引用在各个渲染中保持不变。
我可以这样做以在每次渲染时重新创建 reducer 函数吗?
const initialState = {count: 0};
function Counter() {
// REDUCER FUNCTION WILL BE RECREATED ON EVERY RENDER
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
动机:
我正在研究货币转换器,我的减速器取决于THOUSAND_SEPARATOR
andDECIMAL_SEPARATOR
是点.
或逗号,
,这可能会在渲染之间发生变化,所以我需要在每次渲染时重新创建它。
片段
它似乎有效,但它是一种反模式吗?
function App() {
const initialState = {count: 0};
const [bool,setBool] = React.useState(false);
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: bool ? state.count - 1 : state.count + 1};
case 'decrement':
return {count: bool ? state.count + 1 : state.count - 1};
default:
throw new Error();
}
}
const [state,dispatch] = React.useReducer(reducer, initialState);
return (
<React.Fragment>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => setBool((prevState) => !prevState)}>Invert Direction</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>