0

JavaScript/HTML アプリがあるとします。

  • アイテムを管理します
  • 選択されたアイテムの概念を持っています
  • アプリの実行時にアイテムのリアルタイム更新を取得します。

アプリで不変の状態 (immutable.js、redux、react など) を使用する場合、概念的には、リスト内の項目への更新をアプリの選択した項目と同期させるにはどうすればよいですか?

プレーンな JavaScript オブジェクト/配列とミューテーションを使用している場合、選択されたアイテムは何らかのオブジェクトへの参照になり、アイテムのリストは実際にはアイテム オブジェクトへの参照のリストになります。アイテムのリスト内のオブジェクトのプロパティを変更すると、同じオブジェクトであるため、選択したアイテムと同期されます。

不変状態を使用している場合、同様のものをどのように管理しますか? 選択されたアイテムの更新が行われた場合、リスト内のアイテムが異なり、選択されたアイテムに同じ変換が適用されている新しい状態を返すことも覚えておく必要がありますか?

1つの考えは、選択されたアイテムではなく、選択されたインデックスを持つことですが、アイテムのリストを並べ替えると、選択されたインデックスが異なる新しい状態を返すことを覚えておく必要がありますか?

このようなものに対処するためのパターンはありますか?

4

1 に答える 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 に答える