javascript - 以Redux状态: reflection of API object vs.简化形式状态存储数据

标签 javascript reactjs redux react-redux

假设我有一个Report我的后端模型,其中有 date属性,其类型为 Date 。 React 表单包含两个用于修改它的输入:a <select>有几个月和一个 <input>对于 YYYY 中的日期年份格式。我不关心这一天,因为我将使用 moment.utc(...).endOf('month') 将日期设置为所选年份中所选月份的末尾。 .

对于此任务,我看到两个选项:

  1. 我的 Redux 状态保存着最终计算的 date对象,该对象将被发布到后端,或者
  2. 该状态有两个属性:monthyear然后,当 Report已准备好发布到后端,这两个属性被删除并转换为 date对象。

选项(2)看起来很脏,需要大量的预处理:破坏接收到的 Report对象转换为不属于后端的属性,以及在发布到服务器之前构造所需的属性。

但是,选项 (2) 允许通过 onChange 将 React 组件更清晰地绑定(bind)到状态。和value组件的属性。

选项(1)似乎更明智,因为 Redux 状态是后端状态的表示,但是我发现自己写了很多hacky逻辑:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import moment from 'moment';

import { reportChange } from '../actions';

const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];

class Report extends Component {
  constructor(props) {
    super(props);
    this.handleMonthChange = this.handleMonthChange.bind(this);
  }

  handleMonthChange(event) {
    const { dispatch, report } = this.props,
      { target: { value }} = event,
      date = moment.utc(report.date),
      year = this.yearInput.value,
      month = value;
    date.month(month).year(year).endOf('month');
    dispatch(reportChange({
      date: date.toDate()
    }));
  }

  render() {
    const { report } = this.props;

    return (
      <div>
        <select name="month" value={moment.utc(report.date).format('M')} onChange={this.handleMonthChange}>
          {months.map((month, index) => (<option key={index} value={index + 1}>{month}</option>))}
        </select>
        <input
          name="year"
          value={moment.utc(report.date).format('YYYY')} // this sets initial value of the input
          ref={input => this.yearInput = input} // uncontrolled component
        />
      </div>
    );
  }

  static propTypes = {
    dispatch: PropTypes.func.isRequired,
    report: PropTypes.object.isRequired
  }
}

const mapStateToProps = state => ({
  report: state.report
});

export default connect(mapStateToProps)(Report);

这是一个简短的版本,删除了所有不必要的内容。现在,如您所见,我使用了 uncontrolled component用于年份输入。这是因为如果我将它绑定(bind)到原来的date属性(property)在Report Redux 存储中的对象通过 value={moment.utc(report.date).format('YYYY')}onChange组件变得不可用的属性,它总是绑定(bind)到 YYYY格式,因此您无法删除任何数字 - 它会自动更新为 0201而不是201当您按退格键删除7时来自2017 .

此外,由于这是一个不受控制的组件,因此我必须在所有重大事件中手动提取其值,例如 formonSubmit事件处理程序,用于在提交正确的日期之前更新报表对象等。

我觉得我错过了一些东西,应该有一个更简单的方法。非常感谢任何帮助或建议。

最佳答案

Option (1) seems more sensible, since the Redux state is a representation of the backend's state

我会争论。 Redux 状态应该代表应用程序的状态(无论它是什么,包括未存储在后端的 UI 状态)。因此,选项(2)是可行的方法。此外,它还使组件可重用,因为它们不依赖于后端数据格式。

关于javascript - 以Redux状态: reflection of API object vs.简化形式状态存储数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42971792/

相关文章:

javascript - 存储用户 ID 的最佳解决方案是什么?

javascript - HTML5 和 JavaScript 中每个音频播放器的音量 slider

javascript - 如何将我的 moment js 持续时间值限制为仅 2 位数?

reactjs - React router v4 history.push 到功能组件中的相同路由(不同的查询参数)(使用 Hooks API)

css - 关于我的 react 应用程序中的网格布局的问题

reactjs - 应用启动时使用 Redux 获取用户数据的推荐位置是什么?

javascript - XPCSafeJSObjectWrapper 有什么作用?

html - 使用 CSS 扩展文本框以适应其内容?

javascript - 扩展运算符如何在数组和 obj 中工作?

javascript - 如果对象存在,则更新数组中的对象