Pasando accesorios al componente contenedor react-redux

82

Tengo un componente contenedor react-redux que se crea dentro de un componente React Native Navigator. Quiero poder pasar el navegador como un accesorio a este componente contenedor para que después de presionar un botón dentro de su componente de presentación, pueda empujar un objeto a la pila del navegador.

Quiero hacer esto sin necesidad de escribir a mano todo el código repetitivo que me da el componente contenedor react-redux (y tampoco perderme todas las optimizaciones que me daría react-redux aquí también).

Ejemplo de código de componente de contenedor:

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

Y me gustaría poder llamar al componente de esta manera desde mi renderScenefunción de navegador :

<SearchViewContainer navigator={navigator}/>

En el código del contenedor anterior, necesitaría poder acceder a esta propiedad pasada desde dentro de la mapDispatchToPropsfunción.

No me apetece almacenar el navegador en el objeto de estado redux y no quiero pasar el accesorio al componente de presentación.

¿Hay alguna forma de que pueda pasar un accesorio a este componente de contenedor? Alternativamente, ¿existen enfoques alternativos que estoy pasando por alto?

Gracias.

Miguel
fuente

Respuestas:

119

mapStateToPropsy mapDispatchToPropsambos toman ownPropscomo segundo argumento.

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

Para referencia

Abhinav Singi
fuente
14

Puede pasar un segundo argumento al mapStateToProps(state, ownProps)que le dará acceso a los accesorios pasados ​​al componente en mapStateToProps

Conor Hastings
fuente
¿Cómo puedo acceder a él en mapDispatchToProps?
Michael
2
@Michael de la misma manera, puede usar el segundo argumento
Conor Hastings
6

Hay algunas trampas al hacer esto con mecanografiado, así que aquí hay un ejemplo.

Un problema fue cuando solo está usando dispatchToProps (y no mapeando ningún objeto de estado), es importante no omitir el parámetro de estado (se puede nombrar con un prefijo de subrayado).

Otro problema fue que el parámetro ownProps tenía que escribirse usando una interfaz que contenga solo los accesorios pasados; esto se puede lograr dividiendo su interfaz de accesorios en dos interfaces, por ejemplo

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

El componente se puede declarar pasando el parámetro único:

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

Usando decoradores (@)

Si está utilizando decoradores, el código a continuación ofrece un ejemplo en el caso de que desee utilizar decoradores para su conexión redux.

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

Si ahora marca this.props.Foo, verá el accesorio que se agregó desde donde Barse usó el componente.

<Bar Foo={'Baz'} />

En este caso this.props.Fooserá la cadena 'Baz'

Espero que esto aclare algunas cosas.

Joe Lloyd
fuente