0

假设我有一个 JavaScript/HTML 应用程序

  • 管理项目
  • 有一个选定项目的概念
  • 在应用程序运行时获取项目的实时更新。

如果我希望我的应用程序使用不可变状态(immutable.js、redux、react 等),从概念上讲,如果它们相同,我将如何使列表中项目的更新与应用程序的选定项目保持同步?

如果我使用纯 JavaScript 对象/数组和突变,那么所选项目将是对某个对象的引用,而项目列表实际上是对项目对象的引用列表。如果我更改项目列表中对象的属性,那么它将与所选项目同步,因为它是同一个对象。

如果我使用不可变状态,我将如何管理类似的事情?如果对所选项目进行了更新,我是否还必须记住返回一个新状态,其中列表中的项目不同并且所选项目应用了相同的转换?

一个想法是没有选定的项目,但有一个选定的索引,但是当我重新排序我的项目列表时,我是否必须记住返回一个选定索引不同的新状态?

是否有处理此类事情的模式?

4

1 回答 1

1

这是我这样做的一种方法。您可以将对 index 的引用更改为 item.id。

class JDropSelectRender extends React.Component {
  render() {
    let items = this.props.options.map((option) => {
      if (option.type == 'seperator') {
        return (<div style={DropdownSeperatorSty} key={option.key}></div>)
      } else {
        let selected = Boolean(option.label == this.state.selected.label);
        let labelSpanSty = {cursor: 'pointer'};
        labelSpanSty.color = selected ? 'green' : 'black';
        return (
          <div
            id='DropdownOptionSty'
            key={option.value}
            style={DropdownOptionSty}
            onMouseDown={this.setValue.bind(this, option)}
            onClick={this.setValue.bind(this, option)}
          >
            <span style={labelSpanSty}>{option.label}</span>
          </div>
        )
      }
    });

    let value = (<div style={placeSty}>{this.state.selected.label}</div>);
    let menu = this.state.isOpen ? <div style={DropdownMenuSty}>{items}</div> : null;

    return (
      <div id='DropdownSty' style={DropdownSty}>
        <div
          id='DropdownControlSty'
          style={DropdownControlSty}
          onMouseDown={this.handleMouseDown}
          onTouchEnd={this.handleMouseDown}
        >
          {value}
          <span id='DropdownArrowSty' style={DropdownArrowSty} />
        </div>
        {menu}
      </div>
    )
  }
}

export default class JDropSelect extends JDropSelectRender {
  constructor() {
    super();
    this.state = { isOpen: false, selected: {} };
  }
  componentWillMount() {
    this.setState({selected: this.props.defaultSelected || { label: 'Select...', value: '' }})
  }
  componentWillReceiveProps(newProps) {
    if (newProps.defaultSelected && newProps.defaultSelected !== this.state.selected) {
      this.setState({selected: newProps.defaultSelected});
    }
  }
  handleMouseDown = (event) => {
    if (event.type == 'mousedown' && event.button !== 0) return;
    event.stopPropagation();
    event.preventDefault();
    this.setState({ isOpen: !this.state.isOpen })
  }
  setValue = (option) => {
    if (option !== this.state.selected && this.props.onChange) this.props.onChange(this.props.itemName, option);
    this.setState({ selected: option, isOpen: false });
  }
}

于 2015-11-12T15:48:28.887 回答