存储有关Redux存储中特定实体的状态(加载,错误...)

时间:2017-09-28 10:56:57

标签: reactjs redux

TLDR ;商店中的各个实体可以处于不同的状态,包括加载和错误状态。我们怎样才能在我们的用户界面中正确地反映出这种情况,并且会忘记"处理Redux操作的方法,同时最好保持我们的动作创建者的行为一致吗?

惯例是“开始忘记”#34;一个动作并订阅商店更新,而不是分派一个动作并随后处理它的返回值或承诺。

几个例子说明了这一点:

// This is a web app that lets users create and book events

const loadEvents = () => dispatch => {
  dispatch(loadEventsRequest());

  return fetchFromApi('https://...')
    .then(
      json => dispatch(loadEventsSuccess(json)),
      error => dispatch(loadEventsFailure(error))
    )
}

componentWillMount() {
  this.props.loadEvents(); // Fire it; the state will be updated eventually
}

render() {
  return this.props.events.map((event) => ( <Event event={event} /> ));
}

事件列表可以是几种状态,例如加载状态。我们可以通过设计这样的状态来适应这个:

entities: {
  events: {
    1: {
      title: "Movie night"
    },
    ...
  }
},
visibleEvents: [
  isFetching: false,
  ids: [1, 2, 3]
]

根据visibleEvents.isFetching的值显示加载指标很容易。

特定实体的状态

让我们想象可以预订,取消和删除事件。所有这些操作都可能导致后端错误(&#34;事件已完全预订&#34;)或成功情况(&#34;事件已预订&#34;)。我们可以通过两种方式通知用户:

备选方案1)

从组件中调度操作并使用then / catch对其进行响应。抓到了一个错误?显示它。州保持在当地。

为了实现这一点,我们的loadEvents()动作创建者需要进行更改。目前它会捕获错误并触发loadEventsFailure(),因此我们的组件不知道操作是否失败或成功(无法捕获)。

我们可以从动作创建者那里重新抛出错误或拒绝承诺,(或者根本不抓住它),这样我们的组件就有机会捕获并回应它。我最担心的是,我们的行动创作者最终会出现不一致的行为 - 有些是错误,有些则不是。我们可以使始终抛出错误成为惯例,但除非组件捕获它们,否则我们最终会得到&#34; Uncaught&#34;错误到处都是。

让组件决定动作创建者的行为(是否抛出/拒绝)是不对的,特别是如果其他组件也想要使用它。此外,在这种情况下,预订减速机是没有用的,因为我们的状态永远不需要在预订过程中更新。

备选方案2)

将Redux状态下的每种类型的结果(错误或成功状态)与其特定实体一起存储(即每个事件可以具有与预订,删除和取消相关的多个状态)。

我们的组件不需要&#34;回应&#34;动作创作者;它可以简单地触发一个动作并从Redux状态读取结果(非常独特)。从概念上讲:

handleBookingButtonClicked() { this.props.bookEvent(id); }
// ...
render() { if (store.entities.events[id].bookingError) return (<div>Booking failed</div>); }

与预订活动相关的所有组件都可以阅读bookingError。与取消相关的组件可以阅读cancellationError等。

(注意:如果它在商店中只有一个&#34;全局&#34;错误对象,或者每个实体包含一个与之相关的任何类型错误的错误对象,那么这很快就会很快如果要同时显示多个组件,则会失败。)

这种方法有几个问题:

  • 最终需要清除错误;我们不想无限期地显示错误。
  • 每个事件可能有很多的不同状态指标:加载,预订,删除,取消,更新等。此外,这些指标中的每一个都可以处于不同的状态:预订事件?它可能成功,失败或正在进行中。如果失败了,我们想知道原因。
  • alllows预订的两个不同组件会显示相同的错误。

您会推荐哪种方法,以及如何解决所描述的问题(以及提供一致行动创建者的建议)?

0 个答案:

没有答案