2016-08-24 3 views
3

Kürzlich fing ich an, mobx mit react und mobx-react library zu benutzen.Mobx - Reagieren: Injizieren und Beobachten zusammen

Ich möchte funktionale React-Komponenten verwenden, um meine Ansichten zu erstellen.

Ich möchte eine Hilfsfunktion erstellen, die Selektorfunktion und Component verwendet, Aufrufe injizieren (mit Selektorfunktion als Parameter) und auf dieser Komponente beobachten - diese Komponente effektiv mit dem mobx-react-Speicher verbinden (aus dem Provider-Kontext)) und stellt nur benötigte Eigenschaften für diese Komponente bereit.

Aber ich kann es nicht zur Arbeit bringen. Aktion wird ausgelöst, aber Ansichten reagieren nicht auf diese Änderung (Speicherattribute ändern sich, aber Komponente reagiert nicht auf diese Änderung).

Hier ist meine Helferfunktion:

import { observer, inject } from 'mobx-react'; 

export function connect(selectorFunction, component) { 
    return inject(selectorFunction)(observer(component)); 
} 

hier ist meine Komponente:

import React from 'react'; 
import { connect } from 'utils'; 

const selector = (stores) => { 
    return { 
    counter: stores.counterStore.counter, 
    double: stores.counterStore.double, 
    increment: stores.counterStore.increment 
    }; 
}; 

const Counter = ({ counter, double, increment }) => { 
    return (
    <div className="counter"> 
     <p>{ counter }</p> 
     <p className="double">{ double }</p> 
     <button onClick={increment}>+1</button> 
    </div> 
); 
}; 

export default connect(selector, Counter); 

und hier ist mein Speicher:

import { observable, computed, action } from 'mobx'; 

export default class Counter { 
    @observable counter = 0; 

    @action 
    increment =() => { 
    this.counter++; 
    } 

    @computed 
    get double() { 
    return this.counter * 2; 
    } 
} 

(Nicht zeigt Provider und andere einfache Sachen, aber es ist richtig eingerichtet).

Danke! Jede Antwort wird sehr geschätzt.

Antwort

3

Wenn Sie Mobx documentation betrachten, sieht es so aus, als würde Ihr Selektor etwas falsch machen. Es sollte ein Objekt mit den Geschäften und kein Objekt mit Werten aus Geschäften zurückgeben. Versuchen Sie, die tatsächliche counterStore Rückkehr statt:

const selector = (stores) => { 
    return { 
    counterStore: stores.counterStore 
    }; 
}; 

und es verwenden, wie dies in Ihrer Komponente:

const Counter = ({ counterStore: { counter, double, increment } }) => { 
    return (
    <div className="counter"> 
     <p>{ counter }</p> 
     <p className="double">{ double }</p> 
     <button onClick={increment}>+1</button> 
    </div> 
); 
}; 
+0

Danke für die Antwort! Das könnte ein anderes Problem gelöst haben, von dem ich noch nicht einmal wusste, aber mein früheres Problem besteht immer noch: –

+0

Hm, das ist komisch. Ich habe Ihren Code (lokal auf meinem Computer) verwendet und das von Ihnen beschriebene Problem bemerkt. Nach der Aktualisierung darauf hat es für mich richtig funktioniert. Hoffe, du findest eine Lösung! – tobiasandersen

+0

Der Grund für das aktuelle Verhalten ist, dass nur die 'render' Methode der' observer' Komponente verfolgt wird, nicht die inject Funktion selbst. Das könnte eigentlich interessant sein ... Zum Spaß könnten Sie versuchen, ob das Ihr ursprüngliches Problem löst: 'return observer (inject (selectorFunction) (Beobachter (Komponente)))' siehe auch: https: // github. com/mobxjs/mobx-reagieren/Fragen/111 – mweststrate

-2

export function connect(selectorFunction, mapToProps, component) { 
 
    return inject(selectorFunction)(observer(withProps(mapToProps)(component))); 
 
} 
 

 
export const withProps = (mapToProps: (Object) => Object) => Component => { 
 
    return class extends React.Component { 
 
    render() { 
 
     const mappedProps = mapToProps(this.props) 
 
     return <Component {...mappedProps} {...this.props}/> 
 
    } 
 
    } 
 
} 
 

 
const ConnectedCounter = connect(
 
    (stores) => ({counterStore: stores.counterStore}), 
 
    ({counterStore}) => ({ 
 
    counter: counterStore.counter, 
 
    double: counterStore.double, 
 
    increment: counterStore.increment 
 
    }), 
 
    Counter 
 
)

Verwandte Themen