web-dev-qa-db-fra.com

Passer des accessoires au composant de conteneur react-redux

J'ai un composant conteneur react-redux créé dans un composant React Native Navigator. Je souhaite pouvoir transmettre le navigateur en tant qu'accessoire à ce composant conteneur afin qu'après qu'un bouton soit enfoncé dans son composant de présentation, il puisse insérer un objet dans la pile du navigateur.

Je veux le faire sans avoir besoin d'écrire à la main tout le code standard que me fournit le composant de conteneur react-redux (et de ne pas manquer toutes les optimisations que réact-redux me donnerait ici aussi).

Exemple de code de composant de conteneur:

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

Et j'aimerais pouvoir appeler le composant comme celui-ci à partir de ma fonction de navigateur renderScene:

<SearchViewContainer navigator={navigator}/>

Dans le code de conteneur ci-dessus, il faudrait pouvoir accéder à cet accessoire transmis à partir de la fonction mapDispatchToProps.

Je n'ai pas envie de stocker le navigateur sur l'objet d'état redux et je ne veux pas transmettre l'accessoire au composant de présentation.

Est-il possible de transmettre un accessoire à ce composant conteneur? Sinon, y a-t-il des approches alternatives que je néglige?

Merci.

70
Michael

mapStateToProps et mapDispatchToProps prennent tous deux ownProps comme deuxième argument.

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

Pour référence

108
Abhinav Singi

Vous pouvez passer un second argument à mapStateToProps(state, ownProps) qui vous donnera accès aux accessoires transmis au composant dans mapStateToProps.

11
Conor Hastings

Il y a quelques pièges lorsque vous faites cela avec TypeScript, alors voici un exemple.

Un des pièges était que vous utilisiez uniquement dispatchToProps (et ne mappiez aucun accessoire d'état), il est important de ne pas omettre le paramètre state (il peut être nommé avec un préfixe de soulignement).

Un autre piège était que le paramètre ownProps devait être typé à l'aide d'une interface contenant uniquement les accessoires transmis - ceci peut être obtenu en scindant votre interface d'accessoires en deux interfaces, par exemple.

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);

Le composant peut être déclaré en passant le paramètre unique:

<MyComponent value={event} />
3
Damian Green

Utilisation de décorateurs (@)

Si vous utilisez des décorateurs, le code ci-dessous donne un exemple dans le cas où vous souhaitez utiliser des décorateurs pour votre connexion redux.

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

Si vous vérifiez maintenant this.props.Foo, vous verrez l'accessoire ajouté à partir duquel le composant Bar a été utilisé.

<Bar Foo={'Baz'} />

Dans ce cas, this.props.Foo sera la chaîne 'Baz'

J'espère que cela clarifie certaines choses.

1
Joe Lloyd