2016-09-28 3 views
7

Ich möchte wiederverwendbare Module machen, die in jede react-redux-Anwendung eingesteckt werden können. Im Idealfall würde mein Modul eine Container-Komponente, Aktionen und Reduzierer auf der obersten Ebene haben (und dann alle Präsentations-Komponenten unterhalb des Containers). Ich möchte, dass das Modul nur seinen eigenen Teil des App-Zustands abarbeitet und im Idealfall nichts über den Rest des App-Status wissen muss (es ist also wirklich modular).React Redux - kann ich mapStateToProps veranlassen, nur einen Teil des Zustands zu übernehmen?

Reduzierer arbeiten nur von einem Teil des Staates (mit combineReducers), so bin ich glücklich dort. Bei Container-Komponenten scheint mapStateToProps jedoch immer den vollständigen Status der App zu übernehmen.

Ich würde es gerne, wenn MapStateToProps nur die gleiche "State Slice" nahm, die ich in meinem Modul handhabe (wie der Reducer). So würde mein Modul wirklich modular sein. Ist das möglich? Ich denke, ich könnte dieses Stück des Staates einfach als Requisite dieser Komponente durchgehen (also könnte ich einfach das zweite Argument von mapStateToProps, ownProps verwenden), bin mir aber nicht sicher, ob dies den gleichen Effekt hätte.

+0

AFAIK, wenn 'connect' über' react-redux' verwendet wird, übergibt es immer den gesamten Redu-Speicher an die verbundene Komponente. Daher ist der Job von 'mapStateToProps' genau das. Etwas wie' (state) => ({user: state.user}) 'sollte ausreichen. – lux

+2

Was hast du am Ende? Ich stehe vor dem gleichen Problem –

Antwort

5

, die tatsächlich so etwas wie ein kompliziertes Thema ist. Da Redux ein einziger globaler Speicher ist, wird die Idee eines vollständig gekapselten, vollständig wiederverwendbaren Plug-and-Play-Logiksatzes ziemlich schwierig. Während die Reducer-Logik ziemlich allgemein und unwissend sein kann, wo sie sich befindet, müssen die Selektorfunktionen insbesondere wissen, wo in dem Baum diese Daten zu finden sind.

Die spezifische Antwort auf Ihre Frage ist "nein, mapState wird immer den vollständigen Statusbaum gegeben".

ich Links zu tun haben, eine Reihe von relevanten Ressourcen, die möglicherweise mit Ihrer Situation helfen können:

1

Redux hat nur einen einzigen Speicher, wie Sie wissen, so dass es nur den gesamten Speicher an Ihre mapStateToProps-Funktion übergeben kann. Mit der Destruktu- rierung von Objekten können Sie jedoch festlegen, welche Eigenschaften in dem gewünschten Geschäft gespeichert werden sollen, und den Rest ignorieren. Etwas wie 'Funktion mapStateToProps ({prop1, prop2})' würde nur diese zwei Eigenschaften im Speicher erfassen und den Rest ignorieren. Ihre Funktion erhält immer noch den gesamten Laden, aber Sie geben an, dass nur diese Requisiten Sie interessieren.

In meinem Beispiel wären 'prop1' und 'prop2' die Namen, die Sie während des Aufrufs von 'combinedReducers' Ihren Reduzierern zugewiesen haben.

0

Idealerweise erhalten Sie den Status, und Sie extrahieren die Werte von ihnen mithilfe von Dekonstruktoren. redux arbeitet an Konzept des einzelnen Zustandes

Zum Beispiel: -

function mapStateToProps(state){ 
    const { auth } = state //just taking a auth as example. 
    return{ 
     auth 
    } 
} 
0

Die Antwort auf Ihre Frage ist ja. Beide gegebenen Antworten decken verschiedene Aspekte derselben Sache ab. Zunächst erstellt Redux einen einzelnen Speicher mit mehreren Reduzierungen. So sollten Sie sie wie so kombinieren:

export default combineReducers({ 
    people: peopleReducer, 
    departments: departmentsReducer, 
    auth: authenticationReducer 
}); 

Dann sagen Sie eine DepartmentsList Komponente haben, können Sie nur die departments aus dem Laden zu Ihrer Komponente abbilden müssen (und vielleicht ein paar Requisiten abgebildet Aktionen wie gut):

function mapStateToProps(state) { 
    return { departments: state.departments.departmentsList }; 
} 

export default connect(mapStateToProps, { fetchDepartments: fetchDepartments })(DepartmentsListComponent); 

in Ihrer Komponente Dann ist es im Grunde:

this.props.departments 
this.props.fetchDepartments() 
0

ich in das gleiche Problem laufen, weil, wie Sie gesagt haben, die aktuelle Implementierung von Redux/reagieren-redux für Aufspaltung Reduzierungen auf den Zustand erlaubt nur gut, aber mapDispatchToProps immer passiert den ganzen Staat Baum.

https://stackoverflow.com/a/39757853/444794 ist nicht was ich will, weil es bedeutet, dass wir alle unsere Selektor Logik für jede react-Redux-Anwendung, die unser Modul verwendet, duplizieren müssen.

Meine aktuelle Problemumgehung war, das Stück des Staates als eine Stütze stattdessen durchzulassen. Dies folgt einer Art von kompositorischem Muster, entfernt aber gleichzeitig die Reinheit des direkten Zugriffs auf den Zustand, worüber ich enttäuscht bin.

Beispiel:

Im Allgemeinen wollen Sie dies tun: (. Dh Schlüsselwerte)

const mapStateToProps = (state) => { 
    return { 
    items: mySelector(state) 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    doStuff: (item) => { 
     dispatch(doStuff(item)) 
    } 
    } 
} 

class ModularComponent extends React.Component { 
    render() { 
    return (
     <div> 
     { this.props.items.map((item) => { 
      <h1 onclick={() => this.props.doStuff(item) }>{item.title}</h1> 
     })} 
     </div> 
    ) 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(ModularComponent) 

, aber da dieses Modul in einer Anwendung enthalten ist, wo der Staat nun mehrere Dinge, anstatt eine Liste von Artikeln, das wird nicht funktionieren. Meine Abhilfe sieht statt wie:

const mapStateToProps = (_, ownProps) => { 
    return { 
    items: mySelector(ownProps.items) 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    doStuff: (item) => { 
     dispatch(doStuff(item)) 
    } 
    } 
} 

class ModularComponent extends React.Component { 
    render() { 
    return (
     <div> 
     { this.props.items.map((item) => { 
      <h1 onclick={() => this.props.doStuff(item) }>{item.title}</h1> 
     })} 
     </div> 
    ) 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(ModularComponent) 

Und die Anwendung mit dem Modul wie folgt aussieht:

const mapStateToProps = (state) => { 
    return { 
    items: state.items 
    stuffForAnotherModule: state.otherStuff 
    } 
} 

class Application extends React.Component { 
    render() { 
    return (
     <div> 
     <ModularComponent items={ this.props.items } /> 
     <OtherComponent stuff={ this.props.stuffForAnotherModule } /> 
     </div> 
    ) 
    } 
} 

export default connect(mapStateToProps)(Application) 
0

Obwohl mapStateToProps (die erste Funktion, die Sie verbinden passieren zu) wird den ganzen Laden übergeben, wie Sie gesagt haben, seine Job besteht darin, bestimmte Teile des Status der Komponente zuzuordnen. Daher wird nur das, was von mapStateToProps zurückgegeben wird, als Prop zu Ihrer Komponente zugeordnet.

kann also sagen, dass Ihr Zustand wie folgt aussieht:

{ 
    account: { 
     username: "Jane Doe", 
     email: "[email protected]", 
     password: "12345", 
     .... 
    }, 
    someOtherStuff: { 
     foo: 'bar', 
     foo2: 'bar2' 
    }, 
    yetMoreStuff: { 
     usuless: true, 
     notNeeded: true 
    } 
} 

und Ihre Komponente muss alles von account und foo von someOtherStuff dann mapStateToProps würde wie folgt aussehen:

const mapStateToProps = ({ account, someOtherStuff }) => ({ 
    account, 
    foo: { someOtherStuff } 
}); 
export default connect(mapStateToProps)(ComponentName) 

dann Komponente Lassen Sie die Requisite account und foo von Ihrem Redux-Zustand abbilden.

Verwandte Themen