听取redux动作 [英] Listening for a redux action
问题描述
我想创建一个可重复使用的redux表模块,它将存储和更新页码,显示的总页数等,我可以在所有页面之间共享。
I want to create a reusable redux table module, which will store and update page number, total pages displayed etc, which I can share between all my pages.
但是,我需要更新操作来触发刷新数据操作,该操作将根据页面命中不同的端点。
However I need the update actions to trigger a refreshdata action which will be hitting a different endpoint depending on page.
因此,可能某些特定页面的内容会侦听RefreshData操作,然后触发另一个操作。实现这一目标的最佳方法是什么?我目前正在使用redux-thunk作为我的中间件,但一直在寻找redux-saga。
So maybe something along the lines of a page specific listen for the 'RefreshData' action then trigger another action. What would be the best way of acheiving this? I am currently using redux-thunk for my middleware, but have been looking towards redux-saga.
实现这一目标的最佳方法是什么?
What is the best way to achieve this?
**澄清**
我在多个页面/项目上有表格,我想最小化代码复制。我想我可以制作一个droppable redux模块(action + reducer),然后单独指定REFRESH_DATA操作的处理程序,所以我不需要在这个文件中放置开关。我认为使用redux-saga我可以监听REFRESH_DATA操作并根据当前页面进行切换?或者任何更好的建议。
I have tables on multiple pages / projects and I want to minimize code duplication. I was thinking I could maybe make a droppable redux module (action + reducer), and then just specify the handler for the REFRESH_DATA action separately, so I wouldn't need to put switches in this file. I think with redux-saga I could listen for the REFRESH_DATA action and have a switch depending on current page? Or any better suggestions.
export const ITEMS_PER_PAGE_UPDATED = 'ITEMS_PER_PAGE_UPDATED'
export const CURRENT_PAGE_UPDATED = 'CURRENT_PAGE_UPDATED'
export const REFRESH_DATA = 'REFRESHDATA'
export const DATA_REFRESHED = 'REFRESHDATA'
export function currentPageUpdated(value) {
return function (dispatch) {
dispatch({
type: CURRENT_PAGE_UPDATED,
value
})
dispatch({type:REFRESH_DATA})
}
}
export function itemsPerPageUpdated(value) {
return function (dispatch) {
dispatch({
type: ITEMS_PER_PAGE_UPDATED,
value
})
dispatch({type:REFRESH_DATA})
}
}
function reducer(state={ pageNumber:1, pageSize:10, totalItems:0, totalPages:1, sortColumn:null, sortAscending:true }, action) {
switch(action.type) {
case ITEMS_PER_PAGE_UPDATED:
return Object.assign({}, state, {pageSize: action.value, pageNumber:1})
case CURRENT_PAGE_UPDATED:
return Object.assign({}, state, {pageNumber: action.value})
case DATA_REFRESHED:
return Object.assign({}, state, {totalPages: action.values.totalPages, totalItems:action.values.totalItems})
default:
return state
}
}
export default reducer
推荐答案
如果我理解正确,听起来像 REFRESH_DATA
动作主要是副作用,意味着只有在另一个动作的结果下才会调度动作。如果是这种情况,那么我会说redux saga将是一个不错的选择,因为它可以坐在后台并监听操作,然后触发其他操作。但是,您可以使用自定义的中间件获得相当远的距离。
If I'm understanding correctly, it sounds like the REFRESH_DATA
action is mainly a side effect, meaning that action is only dispatched as a result of another action. If that is the case then I'd say redux saga would be a good choice because it can sit in the background and "listen" for actions and then trigger other actions. But, you may be able to get pretty far with a custom middleware.
使用自定义中间件,您可以在它们命中减速器之前拦截动作。如果您要进行一系列与更新表和刷新数据相关的操作,那么为所有这些操作创建一个通用操作形状可能是有意义的,这样您的中间件就可以监听它并发送特殊的副作用。
With custom middleware you can intercept actions as they are dispatched before they hit the reducers. If you're going to have a bunch of actions all related to updating a table and refreshing data, it might make sense to create a common action shape for all of those kinds of actions so that you're middleware can listen for it and dispatch special side-effect actions.
一个简单的实现可能如下所示:
A simple implementation might look something like this:
middleware / table.js
import fetchData from '../somewhere';
import { DATA_REFRESHED } from '../actions';
// Make a unique identifier that you're actions can send so you're
// middleware can intercept it
export const UPDATE_TABLE = Symbol('UPDATE_TABLE');
export default store => next => action => {
const tableUpdate = action[UPDATE_TABLE];
// If the action doesn't have the symbol identifier, just move on
if (typeof tableUpdate === 'undefined') {
return next(action);
}
// At this point, you know that the action that's been dispatched
// is one that involves updating the table, so you can do a fetch
// for data
// Get whatever data you need to fetch
const { id, type, data } = tableUpdate;
// Dispatch the actual type of action to the store
next({ type, data });
// Go and fetch the data as a side-effect
return fetchData(id)
.then(response => next({ type: DATA_REFRESHED, data: response }));
}
actions.js
import { UPDATE_TABLE } from '../middleware/table.js';
// An action creator to dispatch the special table update action
// This is a simple example, but you'd probably want to be consistent
// about how the table update actions are shaped. The middleware
// should be able to pick out all of the data it needs to fetch data
// from whatever is sent with the action
function updateTable(action) {
return {
[UPDATE_TABLE]: action
};
}
export function currentPageUpdated(value) {
return updateTable({
type: CURRENT_PAGE_UPDATE,
value
});
}
我从现实世界的例子中得到了很多: https://github.com/rackt/redux/blob/master/ examples / real-world / middleware / api.js 。
I took a lot this from the real world example: https://github.com/rackt/redux/blob/master/examples/real-world/middleware/api.js.
这篇关于听取redux动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!