Übergabe der Requisiten an die React-Redux-Containerkomponente

82

Ich habe eine React-Redux-Containerkomponente, die in einer React Native Navigator-Komponente erstellt wird. Ich möchte in der Lage sein, den Navigator als Requisite an diese Containerkomponente zu übergeben, damit er nach dem Drücken einer Schaltfläche in seiner Präsentationskomponente ein Objekt auf den Navigatorstapel schieben kann.

Ich möchte dies tun, ohne den gesamten Boilerplate-Code, den mir die React-Redux-Containerkomponente gibt, von Hand schreiben zu müssen (und auch nicht alle Optimierungen verpassen, die React-Redux mir auch hier geben würde).

Beispiel für einen Containerkomponentencode:

const mapStateToProps = (state) => {
    return {
        prop1: state.prop1,
        prop2: state.prop2
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        onSearchPressed: (e) => {
            dispatch(submitSearch(navigator)) // This is where I want to use the injected navigator
        }
    }
}

const SearchViewContainer = connect(
    mapStateToProps,
    mapDispatchToProps
)(SearchView)

export default SearchViewContainer

Und ich möchte die Komponente in meiner Navigatorfunktion so aufrufen renderScenekönnen:

<SearchViewContainer navigator={navigator}/>

Im obigen Containercode muss ich in der Lage sein, über die mapDispatchToPropsFunktion auf diese übergebene Requisite zuzugreifen .

Ich möchte den Navigator nicht auf dem Redux-Statusobjekt speichern und möchte die Requisite nicht an die Präsentationskomponente weitergeben.

Gibt es eine Möglichkeit, eine Requisite an diese Containerkomponente weiterzugeben? Alternativ gibt es alternative Ansätze, die ich übersehen habe?

Vielen Dank.

Michael
quelle

Antworten:

119

mapStateToPropsund mapDispatchToPropsbeide nehmen ownPropsals zweites Argument.

[mapStateToProps(state, [ownProps]): stateProps] (Function):
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function):

Als Referenz

Abhinav Singi
quelle
14

Sie können ein zweites Argument übergeben, mit mapStateToProps(state, ownProps)dem Sie auf die Requisiten zugreifen können, die in mapStateToProps an die Komponente übergeben wurden

Conor Hastings
quelle
Wie würde ich in mapDispatchToProps darauf zugreifen können?
Michael
2
@ Michael auf die gleiche Weise können Sie das zweite Argument verwenden
Conor Hastings
6

Wenn Sie dies mit Typoskript tun, gibt es ein paar Fallstricke. Hier ist ein Beispiel.

Ein Problem war, wenn Sie nur dispatchToProps verwenden (und keine Status-Requisiten zuordnen), ist es wichtig, den Status-Parameter nicht wegzulassen (er kann mit einem Unterstrich-Präfix benannt werden).

Ein weiteres Problem war, dass der ownProps-Parameter über eine Schnittstelle eingegeben werden musste, die nur die übergebenen Requisiten enthielt. Dies kann erreicht werden, indem Sie die Requisitenschnittstelle in zwei Schnittstellen aufteilen, z

interface MyComponentOwnProps {
  value: number;
}

interface MyComponentConnectedProps {
  someAction: (x: number) => void;
}

export class MyComponent extends React.Component<
  MyComponentOwnProps & MyComponentConnectedProps
> {
....//  component logic
}

const mapStateToProps = (
  _state: AppState,
  ownProps: MyComponentOwnProps,
) => ({
  value: ownProps.value,
});

const mapDispatchToProps = {
  someAction,
};

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

Die Komponente kann durch Übergabe des einzelnen Parameters deklariert werden:

<MyComponent value={event} />
Damian Green
quelle
1

Verwenden von Dekorateuren (@)

Wenn Sie Dekoratoren verwenden, gibt der folgende Code ein Beispiel für den Fall, dass Sie Dekoratoren für Ihre Redux-Verbindung verwenden möchten.

@connect(
    (state, ownProps) => {
        return {
            Foo: ownProps.Foo,
        }
    }
)
export default class Bar extends React.Component {

Wenn Sie jetzt überprüfen this.props.Foo, sehen Sie die Requisite, die von der Stelle hinzugefügt wurde, an der die BarKomponente verwendet wurde.

<Bar Foo={'Baz'} />

In diesem Fall this.props.Foowird die Zeichenfolge 'Baz' sein.

Hoffe das klärt einige Dinge.

Joe Lloyd
quelle