2016-04-03 11 views

Antwort

17

Sie können dies tun, indem Sie den Selektor mithilfe der connect-Methode von react-redux mit einer Komponente verbinden und dann die Komponente requisiten (ownProps) als zweites Argument an den Selektor übergeben.

container.js

import { connect } from 'react-redux'; 
import { getVisibleTodos } from './selectors'; 

... 

const mapStateToProps = (state, props) => { 
    return { 
    todos: getVisibleTodos(state, props), 
    }; 
}; 

const VisibleTodoList = connect(
    mapStateToProps, 
)(TodoList); 

export default VisibleTodoList; 

Sie können dann diese Requisiten in Ihrem Wähler zugreifen

selectors.js

import { createSelector } from 'reselect'; 

const getVisibilityFilter = (state, props) => 
    state.todoLists[props.listId].visibilityFilter; 

const getTodos = (state, props) => 
    state.todoLists[props.listId].todos; 

const getVisibleTodos = createSelector(
    ... 
); 

export default getVisibleTodos; 

Howeve r, dies wird nicht memoize korrekt, wenn Sie mehrere Instanzen der Komponente haben Sie Requisiten aus übergeben. In diesem Fall würde der Selektor jedes Mal ein anderes props-Argument erhalten, also würde er immer neu berechnen, anstatt einen zwischengespeicherten Wert zurückzugeben.

Um einen Wähler über mehrere Komponenten zu teilen, während in Requisiten und Halte memoization vorbei, jede Instanz der Komponente benötigt eine eigene private Kopie des Wählers.

Sie können dies tun, indem Sie eine Funktion erstellen, die bei jedem Aufruf eine neue Kopie des Selektors zurückgibt.

selectors.js

import { createSelector } from 'reselect'; 

const getVisibilityFilter = (state, props) => 
    state.todoLists[props.listId].visibilityFilter; 

const getTodos = (state, props) => 
    state.todoLists[props.listId].todos; 

const makeGetVisibleTodos =() => { 
    return createSelector(
    ... 
); 
} 

export default makeGetVisibleTodos; 

Wenn das mapStateToProps Argument geliefert Gibt eine Funktion anstelle eines Objekts zu verbinden, wird es eine individuelle mapStateToProps Funktion für jede Instanz des Behälters zu schaffen, verwendet werden.

Mit dem im Verstand, können Sie eine Funktion makeMapStateToProps, die einen neuen getVisibleTodos Selektor und gibt eine mapStateToProps Funktion erstellt erstellen, die exklusiven Zugriff auf den neuen Selektor hat:

import { connect } from 'react-redux'; 
import { makeGetVisibleTodos } from './selectors'; 

... 

const makeMapStateToProps =() => { 
    const getVisibleTodos = makeGetVisibleTodos(); 
    const mapStateToProps = (state, props) => { 
    return { 
     todos: getVisibleTodos(state, props), 
    }; 
    }; 
    return mapStateToProps; 
}; 

const VisibleTodoList = connect(
    makeMapStateToProps, 
)(TodoList); 

export default VisibleTodoList; 

Jetzt jede Instanz des VisibleTodosList Container erhält seine eigene mapStateToProps Funktion mit einem privaten getVisibleTodos Selektor. Die Memoisierung funktioniert nun korrekt, unabhängig von der Renderreihenfolge der Container.


Diese angepasst wurde vom Reselect documentation

+0

Hallo (blatently kopiert), habe ich eine Frage dazu bekam: Was, wenn ich will Parameter makeGetVisibleTodos() hinzufügen? Nehmen wir an, ich habe zwei Komponenten, die denselben Selektor für die Parameterauswahl verwenden, aber die Namen ihrer Props sind unterschiedlich. In diesem Fall funktioniert das nicht, weil die zugrunde liegenden 'getTodos' und' getVisibilityFilter' fehlschlagen. Beispiel: 'betterFoobar = (id) => createSelector (foobarSelector, (foobarValue) => id + foobarValue)' Meine Idee so weit: 'mapStateToProps = createStructuredSelector ({enhancedFooBar: (Staat, ownProps) => betterFoobar (ownProps.id) (state, ownProps)}) aber ich denke, das wird nicht memotisieren. –

+0

Um meinen Punkt klarer zu machen, stelle ich diese Frage, weil die Verwendung von ownProps in einem Selektor eine React-Komponenten-API eng an einen Redux-Statusselektor koppelt. Dies macht Selektoren über Komponenten hinweg unbrauchbar, während sie ein äußerst leistungsfähiges Wiederverwendbarkeitswerkzeug sind. Zum Beispiel möchte ich meine Selektoren sowohl im Hauptprozess als auch im Renderprozess eines Elektrons und in mehreren Komponenten verwenden. Die akzeptierte Lösung scheint in diesem Fall nicht geeignet zu sein (aber natürlich beantwortet sie die erste Frage und es könnten nur ein paar Änderungen in meinen Anwendungsfällen nötig sein). –