0

比方說,我有一個JavaScript/HTML應用程序,更新所選的項目與不變的狀態應用程式

  • 管理項目
  • 具有選定項目
  • 獲取實時更新的項目作爲一個概念應用運行。

如果我想我的應用程序使用一成不變的狀態(immutable.js,終極版,反應,等),概念上,我將如何保持更新的項目列表中的同步與應用程序的選擇的項目,如果他們是相同的?

如果我使用普通的JavaScript對象/數組和突變,那麼所選項目將是對某個對象的引用,而項目列表實際上是項目對象的引用列表。如果我更改項目列表中對象的屬性,那麼它將與選定項目同步,因爲它是同一個對象。

如果我使用不可變狀態,我將如何管理類似的東西? 如果對於選定的項目進行了更新,我是否還必須記得返回列表中的項目不同且所選項目應用了相同轉換的新狀態?

一個想法是沒有選定的項目,但有一個選定的索引,但是當我重新排列我的項目列表時,我必須記得返回一個新的狀態,其中選定的索引是不同的?

是否有模式來處理這樣的事情?

回答

1

這是我這樣做的一種方式。您可以將對索引的引用更改爲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 }); 
 
    } 
 
}

相關問題