企业应*_*式大师 100 javascript reactjs redux
我是React/Redux的新手.我在Redux应用程序中使用fetch api中间件来处理API.这是https://github.com/agraboso/redux-api-middleware.我认为这是处理异步api操作的好方法.但我发现一些自己无法解决的案例.
作为主页https://github.com/agraboso/redux-api-middleware#lifecycle比如说,一个取API生命周期开始派遣CALL_API行动派遣FSA行动结束.
所以我的第一个案例是在获取API时显示/隐藏预加载器.中间件将在开始时发送FSA操作,并在最后发送FSA操作.这两个动作都是由减速器接收的,减速器应该只进行一些正常的数据处理.没有UI操作,没有更多操作.也许我应该将处理状态保存在状态中,然后在存储更新时呈现它们.
但是怎么做呢?一个反应组件流过整个页面?从其他操作更新商店会发生什么?我的意思是他们更像是事件而非国家!
即使是更糟糕的情况,当我必须在redux/react应用程序中使用本机确认对话框或警报对话框时,我该怎么办?它们应该放在哪里,行动还是减少?
最好的祝愿!希望回复.
Dan*_*mov 146
我的意思是他们更像是事件而非国家!
我不会这么说.我认为加载指标是UI的一个很好的例子,很容易被描述为状态的函数:在这种情况下,是一个布尔变量.虽然这个答案是正确的,但我想提供一些代码来配合它.
在asyncRedux repo的示例中,reducer 更新了一个名为的字段isFetching:
case REQUEST_POSTS:
return Object.assign({}, state, {
isFetching: true,
didInvalidate: false
})
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: false,
didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
Run Code Online (Sandbox Code Playgroud)
该组件使用connect()从阵营终极版订阅商店的状态和收益isFetching作为的一部分mapStateToProps()返回值,以便它在连接组件的道具可供选择:
function mapStateToProps(state) {
const { selectedReddit, postsByReddit } = state
const {
isFetching,
lastUpdated,
items: posts
} = postsByReddit[selectedReddit] || {
isFetching: true,
items: []
}
return {
selectedReddit,
posts,
isFetching,
lastUpdated
}
}
Run Code Online (Sandbox Code Playgroud)
最后,组件使用函数中的isFetchingproprender()来呈现"Loading ..."标签(可以想象它是一个微调器):
{isEmpty
? (isFetching ? <h2>Loading...</h2> : <h2>Empty.</h2>)
: <div style={{ opacity: isFetching ? 0.5 : 1 }}>
<Posts posts={posts} />
</div>
}
Run Code Online (Sandbox Code Playgroud)
即使是更糟糕的情况,当我必须在redux/react应用程序中使用本机确认对话框或警报对话框时,我该怎么办?它们应该放在哪里,行动还是减少?
任何副作用(并显示对话框肯定是副作用)不属于reducer.将减速器视为被动的"国家建设者".他们并没有真正"做"事情.
如果您希望显示警报,请在发送操作之前从组件执行此操作,或者从操作创建者执行此操作.在调度动作时,为了响应它而执行副作用为时已晚.
对于每个规则,都有一个例外.有时你的副作用逻辑是如此复杂,你实际上想要将它们耦合到特定的动作类型或特定的减速器.在这种情况下,请查看Redux Saga和Redux Loop等高级项目.只有当你对香草Redux感到舒服并且有一个真正的分散副作用问题时才能做到这一点,你想让它更易于管理.
Nun*_*pos 19
伟大的回答丹阿布拉莫夫!只是想补充说我在我的一个应用程序中做了或多或少的操作(将isFetching保留为布尔值)并最终必须使其成为一个整数(最终读取为未完成请求的数量)以支持多个同时要求.
用布尔值:
请求1开始 - >微调器开启 - >请求2开始 - >请求1结束 - >微调器关闭 - >请求2结束
带整数:
请求1开始 - >旋转器开启 - >请求2开始 - >请求1结束 - >请求2结束 - >旋转器关闭
case REQUEST_POSTS:
return Object.assign({}, state, {
isFetching: state.isFetching + 1,
didInvalidate: false
})
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: state.isFetching - 1,
didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
Run Code Online (Sandbox Code Playgroud)
jav*_*sco 13
我想补充一些东西.真实世界示例使用isFetching商店中的字段来表示何时获取项目集合.任何集合都通用于paginationreducer,可以连接到组件以跟踪状态并显示集合是否正在加载.
碰巧我想要获取不符合分页模式的特定实体的详细信息.我希望有一个状态来表示是否从服务器获取了详细信息,但我也不想为此设置一个reducer.
为了解决这个我添加了另一个叫做通用减速fetching.它的工作方式与分页缩减器类似,它的职责就是观察一组动作并用对生成新的状态[entity, isFetching].这允许connectreducer到任何组件并且知道app当前是否正在获取数据而不仅仅是针对集合而是针对特定实体.
直到现在我才发现这个问题,但由于没有接受答案,我会戴上帽子.我为这个工作写了一个工具:react-loader-factory.它比阿布拉莫夫的解决方案稍微多了一些,但是更加模块化和方便,因为我不想在写完之后再去思考.
有四大块:
const loaderWrapper = loaderFactory(actionsList, monitoredStates);connect()在Redux中返回的那样),因此您可以将它固定在现有的东西上.const LoadingChild = loaderWrapper(ChildComponent);ACTION_SUCCESS和ACTION_REQUEST,例如).(当然,您可以在其他地方发送操作,只需从包装器进行监控.)模块本身独立于redux-api-middleware,但这就是我使用它,所以这里是README的一些示例代码:
包含Loader的组件:
import React from 'react';
import { myAsyncAction } from '../actions';
import loaderFactory from 'react-loader-factory';
import ChildComponent from './ChildComponent';
const actionsList = [myAsyncAction()];
const monitoredStates = ['ASYNC_REQUEST'];
const loaderWrapper = loaderFactory(actionsList, monitoredStates);
const LoadingChild = loaderWrapper(ChildComponent);
const containingComponent = props => {
// Do whatever you need to do with your usual containing component
const childProps = { someProps: 'props' };
return <LoadingChild { ...childProps } />;
}
Run Code Online (Sandbox Code Playgroud)
要监控的Loader的减速器(尽管您可以根据需要以不同的方式连接它):
export function activeRequests(state = [], action) {
const newState = state.slice();
// regex that tests for an API action string ending with _REQUEST
const reqReg = new RegExp(/^[A-Z]+\_REQUEST$/g);
// regex that tests for a API action string ending with _SUCCESS
const sucReg = new RegExp(/^[A-Z]+\_SUCCESS$/g);
// if a _REQUEST comes in, add it to the activeRequests list
if (reqReg.test(action.type)) {
newState.push(action.type);
}
// if a _SUCCESS comes in, delete its corresponding _REQUEST
if (sucReg.test(action.type)) {
const reqType = action.type.split('_')[0].concat('_REQUEST');
const deleteInd = state.indexOf(reqType);
if (deleteInd !== -1) {
newState.splice(deleteInd, 1);
}
}
return newState;
}
Run Code Online (Sandbox Code Playgroud)
我预计在不久的将来,我会在模块中添加超时和错误等内容,但模式不会有太大差异.
你问题的简短回答是:
Spo*_*ck 5
我是唯一一个认为加载指标不属于 Redux 商店的人吗?我的意思是,我不认为这本身就是应用程序状态的一部分。
现在,我使用 Angular2,我所做的是我有一个“加载”服务,它通过 RxJS BehaviourSubjects 公开不同的加载指标。我猜机制是一样的,我只是不将信息存储在 Redux 中。
LoadingService 的用户只需订阅他们想要收听的事件。
我的 Redux 操作创建者在需要更改时调用 LoadingService。UX 组件订阅公开的 observables...
您可以使用connect()React Redux 或低级store.subscribe()方法将更改监听器添加到您的存储中。您的商店中应该有加载指示器,商店更改处理程序可以检查并更新组件状态。然后,如果需要,该组件会根据状态呈现预加载器。
alert应该confirm不是问题。它们是阻塞的,警报甚至不接受用户的任何输入。使用confirm,如果用户选择会影响组件渲染,您可以根据用户单击的内容设置状态。如果没有,您可以将选择存储为组件成员变量以供以后使用。
| 归档时间: |
|
| 查看次数: |
84549 次 |
| 最近记录: |