这是关于真实世界ReactJS 使用以及我们在Threat Stack中了解如何扩展我们的应用程序的一系列博客文章中的第二篇。
在这篇文章中,我们将展示基于第 1 部分中所示的 api 中间件的操作。
当涉及到正在创建的产品和应用程序的类型时,确保所有团队成员始终处于同一页面上至关重要。ReactJS 需要一定的学习曲线,但一旦人们有时间弄清楚它,就可以克服它。
公平地说,学习一个全新的系统并不总是世界上最容易的事情,但是很多人已经学会了如何让 ReactJS为他们工作,我们想要认识这些人并使其非常清楚这是可以完成的事情。
无论如何,每个人都应该想了解 ReactJS,因为它可能很快就会成为他们生活中更重要的一部分。
在这篇文章中,我们将展示基于第 1 部分中所示的 api 中间件的操作。
仍然确保回答这些问题:
有时会出现一个看似简单的功能请求,如下所示:
如果 X 发生了 Y,但前提是状态看起来像 Z。
由于您希望保持代码在 react(视图)和 redux(数据管理)之间解耦,因此像这样的简单请求最终看起来比应有的更困难。
一个很好的例子是 客户端跟踪。
在某些时候,您会想要,不,需要跟踪用户何时单击某物并传递显示中有多少项目或有关当前状态的其他信息。
第一步是 分析中间件。
事情是基于一个恰当地命名为“分析”的属性。
所以动作看起来像这样:
return { types: [ MARK_READ, MARK_READ_SUCCESS, MARK_READ_ERROR ], callAPI: () => Api.updateTodos({ ids, isRead: true }), analytics: { [MARK_READ_SUCCESS] : { idsCount: ids.length, isSuccess: true }, [MARK_READ_ERROR] : { idsCount: ids.length, isSuccess: false } }}
到目前为止……并不可怕。
根据事件类型(成功/错误),我们可以跟踪不同的事情。
但是一个新的要求进来了…… 你不会相信接下来发生的事情。
如果成功,我们还需要将用户重定向到不同的部分。
return { types: [ MARK_READ, MARK_READ_SUCCESS, MARK_READ_ERROR ], callAPI: () => Api.updateTodos({ ids, isRead: true }), analytics: { [MARK_READ_SUCCESS] : { idsCount: ids.length, isSuccess: true }, [MARK_READ_ERROR] : { idsCount: ids.length, isSuccess: false } }, redirect: ({ state }) { }}
我们制作了另一个寻找特定属性的中间件。
我们确实做到了。
但这不会扩展。
我们需要更通用的东西,可以针对不同的用例进行扩展。
设想:
if I'm filtering a list of todos If I mark all as read clear the filter If I mark only some of them as read leave the filter onOnError show an error notification
规则:
component.react.js
handleMarkRead (ids) { dispatch(markReadTodos(ids));}
action.js
import { clearTodosFilter } from '../filterActions';import { MARK_READ, MARK_READ_SUCCESS, MARK_READ_ERROR} from '../constants'export function updateItem (ids) { return { types: [ MARK_READ, MARK_READ_SUCCESS, MARK_READ_ERROR ], callAPI: () => Api.updateTodos({ ids, isRead: true }), effect ({ dispatch, state, type }) { if (type === MARK_READ_ERROR) { dispatch(showErrNotification( 'There was an error updating your todos' )); } if (type === MARK_READ_SUCCESS) { const { todosById } = this.state; let hasReadAll = true; for ( const id in todosById) { if (!todosById[id].isRead) { hasReadAll = false; break; } } if (hasReadAll) { dispatch(clearTodosFilter()); } } }, };}
设想:
当用户更新项目时,如果失败则显示错误通知。
如果成功,则显示不同的通知,但前提是项目为 FOO 或其他状态已更改。
.
item.react.js
handleUpdateItem (item) { dispatch(updateItem({ item });}
ItemActions.js
import { showErrNotifcation } from '../notificationActions';import { UPDATE_ITEM, UPDATE_ITEM_SUCCESS, UPDATE_ITEM_ERROR, MAX_CHANGES} from '../constants'export function updateItem ({ item, prevItem }) { return { types: [ UPDATE_ITEM, UPDATE_ITEM_SUCCESS, UPDATE_ITEM_ERROR ], callAPI: () => Api.updateItem(item), effect ({ dispatch, state, type }) { if (type === UPDATE_ITEM_ERROR) { dispatch(showErrNotification('Error updating item')); } if (type === UPDATE_ITEM_SUCCESS) { const { itemsById } = this.state; if (itemsById[item.id].changes === MAX_CHANGES) { dispatch(showNotification( `You can no longer alter this item` )); } } }, };}
effectsMiddleware.js
export default function effectsMiddleware ({ dispatch, getState }) { return next => action => { const nextValue = next(action); if (!action.effect) { if (!isFunction(action.effect)) { throw new Error('Expected effect to be a function'); } action.effect({ dispatch : dispatch, state : getState(), type : action.type, }); delete action.effect; } return nextValue; };}
但是,您需要确保将其放置在您的其他自定义中间件之后。
const middleware = process.env.NODE_ENV === 'production' ? [ thunk, callAPIMiddleware, effectsMiddleware ] : [ thunk, callAPIMiddleware, effectsMiddleware, logger() ];
留言与评论(共有 0 条评论) “” |