xml ui - reducer
useReducer
may be used as an alternative to useState
.
const [state, dispatch] = useReducer(reducer, initialState, lazyInitFunction)
Ideal for complex state logic where there's a dependency on previous state values or a lotta state sub values
const initialState = { width: 15 }
const reducer = (state, action) => {
switch (action) {
case 'plus':
return { width: state.width + 15 }
case 'minus':
return { width: Math.max(state.width - 15, 2) }
default:
throw new Error("what's going on?" )
}
}
const Bar = () => {
const [state, dispatch] = useReducer(reducer, initialState)
return <>
<div style={{ background: 'teal', height: '30px', width: state.width }}></div>
<div style={{marginTop: '3rem'}}>
<button onClick={() => dispatch('plus')}>Increase bar size</button>
<button onClick={() => dispatch('minus')}>Decrease bar size</button>
</div>
</>
}
render(Bar)
以lazy函数返回设置初始状态
const initializeState = () => ({
width: 100
})
// ✅ note how the value returned from the fn above overrides initialState below:
const initialState = { width: 15 }
const reducer = (state, action) => {
switch (action) {
case 'plus':
return { width: state.width + 15 }
case 'minus':
return { width: Math.max(state.width - 15, 2) }
default:
throw new Error("what's going on?" )
}
}
const Bar = () => {
const [state, dispatch] = useReducer(reducer, initialState, initializeState)
return <>
<div style={{ background: 'teal', height: '30px', width: state.width }}></div>
<div style={{marginTop: '3rem'}}>
<button onClick={() => dispatch('plus')}>Increase bar size</button>
<button onClick={() => dispatch('minus')}>Decrease bar size</button>
</div>
</>
}
render(Bar)
模拟this.setState的merge行为
const initialState = { width: 15 }
const reducer = (state, newState) => ({
...state,
width: newState.width
})
const Bar = () => {
const [state, setState] = useReducer(reducer, initialState)
return <>
<div style={{ background: 'teal', height: '30px', width: state.width }}></div>
<div style={{marginTop: '3rem'}}>
<button onClick={() => setState({width: 100})}>Increase bar size</button>
<button onClick={() => setState({width: 3})}>Decrease bar size</button>
</div>
</>
}
render(Bar)