9

我习惯于在Ember Object Model中计算属性。这是一种指定依赖于其他属性的计算属性的便捷方式。

fullName取决于firstNameand lastName,我可以将计算属性设置为函数computeProperties并在computeProperties每次进行更改时调用。

例子:

function computeFullName(state) {
  const fullName = state.get('firstName') + state.get('lastName');
  const nextState = state.set('fullName', fullName);
  return nextState;
}

function computeProperties(state) {
  const nextState = computeFullName(state);
  return nextState;
}

// store action handler
[handleActionX](state) {

  let nextState = state.set('firstName', 'John');
  nextState = state.set('lastName', 'Doe');

  nextState = computeProperties(nextState);

  return nextState;
}

有没有办法自动设置计算属性,这样我就不必每次都调用额外的函数。在 Redux 或 ImmutableJS 中。

4

4 回答 4

11

Redux 作者在这里!

按照 WildService 的建议使用重新选择是可行的方法。我认为我们不会将它包含在核心中,因为重新选择可以很好地完成它的工作,并且我们可以将它作为一个单独的库。

我想注意几点:

  • 即使重新选择,您也不希望在 reducer 中计算数据。选择器应该减速器管理的状态上运行。换句话说,选择器是你的 Redux 存储状态和你的组件之间的一步——它们不在你的 reducer 中。保持 Redux 状态标准化非常重要,以便于更新。

  • 我们实际上鼓励您在相关的 reducer旁边定义选择器,这样当您更改状态形状时,您不必更改您的组件——它们将使用选择器。你可以在Flux 比较的 Redux 文件夹中看到一个这样的例子

  • 我们有一个文档页面,介绍了重新选择并描述了如何使用它来计算派生数据。看看这个。

于 2015-10-03T12:17:54.300 回答
4

签出重新选择。可组合的纯函数,用于有效计算来自商店的派生数据。Afaik 计划在某个阶段将 reselect 的选择器引入 Redux 核心,如果它们被证明很受欢迎的话。在自述文件的底部也有一个使用 ImmutableJS 的示例。

于 2015-08-02T13:50:48.167 回答
1

要创建计算属性,您可以使用独立的 observable 库mobservable

var user = mobservable.props({
  firstName: 'John',
  lastName: 'Doe',
  fullName: function() {
    return this.firstName + this.lastName
  }
});

var nameViewer = mobservable.ObservingComponent(React.createClass({
   render: function() {
       return (<span>{user.fullName}</span>)
   }
});

这应该是它的要点,现在对 user.firstName 或 lastName 的任何更改都将重新呈现您的 nameViewer 组件。您可以进一步将其与 redux 等通量实现结合以更改数据,并将用户本身推送到您的组件树中。但请注意,用户对象本身不是不可变的(在这种情况下,它毕竟是不可观察的 ;-))对于一些示例,另请参阅这个微不足道稍微有趣的小提琴。

于 2015-07-23T18:46:36.330 回答
0

这样的事情呢?

export const getWidgetsWithComputedProps = widgets => {
  return widgets.map(w => getWidgetWithComputedProps(w));
};

export const selectWidgetType = widget => {
  switch (widget.type) {
    case 'line':
      return 'time-series';
    case 'pie':
    case 'bar':
      return 'cross-sectional';
    default:
      console.warn('Back up: that type of widget does not exist!', widget.type);
      return null;
  }
};

export const getWidgetWithComputedProps = createSelector(
  widget => widget,
  selectWidgetType,
  (widget, _type) => {
    return {...widget, _type}
  }
);
于 2016-10-31T09:57:53.360 回答