2017-09-19 1 views
1

Je the following app qui me permet de cliquer sur todos dans une liste et seulement avoir un todo sélectionné à la fois:Comment restituer uniquement les éléments désélectionnés et sélectionnés avec MobX?

class State { 
    @observable todos = [ 
    { id: '1', description: 'Do this' }, 
    { id: '2', description: 'Do that' }, 
    { id: '3', description: 'Do this third thing' } 
    ] 
} 

const state = new State(); 

const TodoView = observer(({ todo, isSelected, onClick }) => (
    <div onClick={onClick}> 
    { todo.description } { isSelected && ' (selected)' } 
    </div> 
)); 

@observer 
class App extends Component { 
    @observable selected = null; 
    render() { 
    return <div> 
     { state.todos.map((todo) => 
     <TodoView 
     key={todo.id} 
     todo={todo} 
     isSelected={this.selected === todo} 
     onClick={() => this.selected = todo} /> 
     )} 
    </div>; 
    } 
} 

est re-rendu lorsque je sélectionne une nouvelle todo La liste complète des todos. Y a-t-il un moyen de simplement restituer les todos sélectionnés et désélectionnés, sans encombrer l'état avec des données supplémentaires?

Répondre

0

Au lieu d'avoir un selected observable dans le composant App que chaque TodoView repose sur, vous pouvez utiliser un map observable et donner à chaque TodoView une clé propre à observer. Passez ce map comme un accessoire au TodoView et vérifiez si le map a l'ID du todo comme une clé. This way only the selected and deselected todos will be re-rendered:

class State { 
    @observable todos = [ 
    { id: '1', description: 'Do this' }, 
    { id: '2', description: 'Do that' }, 
    { id: '3', description: 'Do this third thing' } 
    ] 
} 

const state = new State(); 

const TodoView = observer(({ todo, selectedMap, onClick }) => (
    <div onClick={onClick}> 
    { todo.description } { selectedMap.has(todo.id) && ' (selected)' } 
    </div> 
)); 

@observer 
class App extends Component { 
    selectedMap = observable.map({}); 

    onClick = (todo) => { 
    this.selectedMap.clear(); 
    this.selectedMap.set(todo.id, todo); 
    }; 

    render() { 
    return <div> 
     { state.todos.map((todo, idx) => 
     <TodoView 
     key={todo.id} 
     todo={todo} 
     selectedMap={this.selectedMap} 
     onClick={() => this.onClick(todo)} /> 
     )} 
    </div>; 
    } 
}