我正在使用react / redux构建我的应用程序。有多个按钮,应用程序需要跟踪是否单击这些按钮的状态。这些按钮都使用相同的reducer逻辑,即在单击按钮时将状态从true切换为false。唯一的区别是国家的名称。有没有办法通过定义"全局"来减少我的代码?可以应用于多个状态的减速器?请参阅此图片以获取example
谢谢!
答案 0 :(得分:2)
我就是这样做的。而不是为每个按钮类型(例如MENU_BTN
,SEARCH_BTN
等)分派唯一操作。我会调度{ type: 'TOGGLE_BUTTON', payload: 'menu' }
并在减速器中
case TOGGLE_BUTTON:
return {
[payload]: !state[payload]
...state
}
然后您可以像这样切换按钮
const toggleButton = key => ({
type: 'TOGGLE_BUTTON',
payload: key
})
dispatch(toggleButton('menu'))
dispatch(toggleButton('search'))
通过这种方式,您可以根据需要跟踪多个按钮。您的州将看起来像这样
...
buttons: {
menu: true,
search: false
}
...
您可以轻松地为每个按钮编写选择器
// Component displaying state of menu button //
let MyComponent = ({ menuButtonState }) => (
<div>
Menu button is {menuButtonState ? 'on' : 'off'}
</div>
)
// Helper function for creating selectors //
const createGetIsButtonToggledSelector = key => state => !!state.buttons[key]
// Selector getting state of a menu button from store //
const getIsMenuButtonToggled = createGetIsButtonToggledSelector('menu')
// Connecting MyComponent to menu button state //
MyComponent = connect(state => ({
menuButtonState: getIsMenuButtonToggled(state)
})(MyComponent)
答案 1 :(得分:0)
您可以创建一个通用高阶归约器,该接受器既接受给定的归约器功能,又接受名称或标识符。
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
function createNamedWrapperReducer(reducerFunction, reducerName) {
return (state, action) => {
const { name } = action
const isInitializationCall = state === undefined
if (name !== reducerName && !isInitializationCall) return state
return reducerFunction(state, action)
}
}
const rootReducer = combineReducers({
counterA: createNamedWrapperReducer(counter, 'A'),
counterB: createNamedWrapperReducer(counter, 'B'),
counterC: createNamedWrapperReducer(counter, 'C')
})
上面的 createdNamedWrapperReducer()方法应该可以直接使用。
有关更多详细说明或更多示例,请参见Redux's recipes for Reusing Reducer Logic。