2017-03-28 1 views
0

Toute aide appréciée:MOBX Perdre état lorsque la méthode (fonction) appelle composant enfant dans le composant parent (jsFiddle demo)

MOBX semble perdre l'état entre les composantes de l'enfant et les parents.

J'ai fait une démo Fiddle ci-dessous. Inclut les commentaires et la sortie pour plus de clarté.

(versions actuelles REACT, MOBX et MOBX-REACT)

Merci.

jsFiddle ICI DEMO

https://jsfiddle.net/ymp1g6qk/3/

DE DÉMO ICI SCREENSHOT

enter image description here

SORTIE CONSOLE ICI

Console Output showing component life cycle and 'unassigned' upon event.

l'exemple de code ICI:

const {observable, computed, extendObservable} = mobx; 
const {observer} = mobxReact; 
const {Component} = React; 
const {render} = ReactDOM 
const {autorun} = mobx 

class MyItem { 
    id = 0; 
    @observable name = ""; 
    @observable selected = false; 
    constructor(id, name, selected) { 
    this.id = id; 
    this.name = name; 
    this.selected = selected;} 
} 



/* ESTIMATE STORE */ 
// @observable <---- Observable not allowed. Generates "Not a Constructor Error" 
class MyStore extends Component { 

    @observable items = []; 

    constructor() { 
    super(); 

    this.items.push(new MyItem(1, 'copper' )); 
    this.items.push(new MyItem(10, 'Silver' )); 
    this.items.push(new MyItem(20, 'Gold' )); 
    this.items.push(new MyItem(30, 'Platinum')); 
    this.items.push(new MyItem(40, 'Sapphire')); 
    this.items.push(new MyItem(50, 'Diamond')); 

    console.log("finished with MyStore:", this.items, " with count: ", this.items.length, " items."); 

    } 

} 
let MyItems = new MyStore(); 



@observer 
class MyCard extends Component { 
    constructor(props){ 
    super(props) 
    } 

    _toggle(e){ 
    console.log("... At (Child) Component"); 
    console.log("click event generates id:", e, "...and calls parent component function that was passed as a prop. (it succeeds)"); 
    this.props.onToggleSelection(e); 

    } 

    render() { 

    return (
     <li onClick={this._toggle.bind(this, this.props.id)} className={(this.props.selected ? " selected" : "")}> 
     <p>{this.props.name}</p> 
     </li> 
    ) 

    } 
} 


@observer 
class Test extends Component { 

    /* selections */ 
    item = 0; 
    @observable selectedMyItems = []; 

    @computed get itemsSelected() { 
    return this.selectedMyItems.length; 
    } 

    constructor(props){ 
    super(props); 

    } 


    componentWillReceiveProps(nextProps, nextContext) { 
    console.log(" ...At panel will recieve props and selectedMyItems:", this.selectedMyItems.length); 
    } 





    componentDidMount() { 
    console.log(" ...At DidMount, and selectedMyItems:", this.selectedMyItems.length); 
    } 


    shouldComponentUpdate(nextProps, nextState, nextContext) { 
    console.log(" ...At ShouldUpdate, and selectedMyItems:", this.selectedMyItems.length); 
    return null; 
    } 


    componentWillUpdate(nextProps, nextState, nextContext) { 
    console.log(" ...At WillUpdate and selectedMyItems:", this.selectedMyItems.length); 
    } 


    componentDidUpdate(prevProps, prevState, prevContext) { 
    console.log(" ...At DidUpdate and selectedMyItems:", this.selectedMyItems.length); 
    } 


    componentWillUnmount() { 
    console.log(" ...At DidUnmount and selectedMyItems:", this.selectedMyItems.length); 
    } 


    toggleSelection(id){ 

    var itemindex = -1; 

    console.log("...At (parent) _toggle selection:", id); 

    /* find the clicked item */ 
    itemindex = MyItems.items.findIndex((MyItem => MyItem.id == id)); 

    console.log("...the id of the item is :", id); 
    console.log("...the item's index is:", itemindex); 
    console.log("...the record for that id is:", MyItems.items[itemindex]); 
    console.log("...selected items array consists of:", this.selectedMyItems); // <<< Warning: "Undefined" 
    console.log("...See??? The array is undefined:", this.selectedMyItems); 

    /* toggle selected */ 
    MyItems.items[itemindex].selected = !MyItems.items[itemindex].selected; // <<< Succeeds. 

    /* add or remove the selected item */ 
    if (MyItems.items[itemindex].selected) { 
     /* add the item to the list of selected items */ 
     console.log("...See??? The next line's push to the array fails: undefined:", this.selectedMyItems); 
     this.selectedMyItems.push(id);     // <<< ERROR: "Cannot read property 'push' of undefined" 

    } else { 
     /* remove the item from the list of selected items */ 
     this.selectedMyItems.splice(this.selectedMyItems.indexOf(id), 1); // <<< ERROR: "Cannot read property 'splice' of undefined" 
    } 

    // this.props.uistore.doCommand({cmd: "TOGGLE_PANEL_SELECTION", pld:{ panelname:"estimate", id: choice }}); 

    } 

    render() { 

    var i = 1; 
    return (

     <div id="my-panel"> 
     Open the Console.<br/> 
     Click on an item in the list to select or unselect it.<br/> 
     Note that selectedMyItems is out of scope (unassigned). Why? 
     <ul className=""> 
      {MyItems.items.map(MyItem => { 
      return (
       <MyCard key={i++} id={MyItem.id} name={MyItem.name} selected={MyItem.selected} tags={MyItem.tags} onToggleSelection={this.toggleSelection}/> 
      ) 
      })} 
     </ul> 
     <ul className=""></ul> 
     </div> 

    ); 
    } 
}; 

ReactDOM.render(<Test/>, app); 
+0

'Observable pas permis. Génère "Pas une erreur de constructeur" '. Vous devriez utiliser le décorateur '@ observateur', pas' @ observable', lors de la création d'un composant dans un observateur. – Tholle

+0

ce n'est pas un observateur. C'est observable. c'est un magasin. –

+0

Vous avez raison. Désolé pour ça. Il n'y a aucun besoin de mettre n'importe quel décorateur sur la classe de magasin elle-même. – Tholle

Répondre

0

Méthode toggleSelection(id) en class Test n'a pas été lié.

Vous devez lier dans le constructeur de test de classe (preféré):

class Test extends Component { 
    constructor() { 
     this.toggleSelection = this.toggleSelection.bind(this); 
    } 

    ... 
} 

ou lier "en place":

<MyCard ... onToggleSelection={this.toggleSelection.bind(this)}/> 

Check version mise à jour jsFiddle: https://jsfiddle.net/ymp1g6qk/6/