Передача props в компонент контейнера react-redux

85

У меня есть компонент контейнера response-redux, который создается в компоненте React Native Navigator. Я хочу иметь возможность передавать навигатор в качестве опоры этому компоненту контейнера, чтобы после нажатия кнопки внутри его презентационного компонента он мог помещать объект в стек навигатора.

Я хочу сделать это без необходимости вручную писать весь шаблонный код, который дает мне контейнерный компонент react-redux (а также не пропустить все оптимизации, которые response-redux также даст мне здесь).

Пример кода компонента контейнера:

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

И я бы хотел иметь возможность вызывать такой компонент из моей renderSceneфункции навигатора :

<SearchViewContainer navigator={navigator}/>

В приведенном выше коде контейнера я должен иметь доступ к этой переданной опоре изнутри mapDispatchToProps функции.

Я не хочу хранить навигатор в объекте состояния redux и не хочу передавать опору презентационному компоненту.

Есть ли способ передать опору этому компоненту контейнера? В качестве альтернативы, есть ли какие-либо альтернативные подходы, которые я упускаю?

Благодарю.

Майкл
источник

Ответы:

120

mapStateToPropsи mapDispatchToPropsоба принимают ownPropsв качестве второго аргумента.

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

Для справки

Абхинав Синги
источник
15

Вы можете передать второй аргумент, mapStateToProps(state, ownProps)который предоставит вам доступ к реквизитам, переданным в компонент в mapStateToProps.

Конор Гастингс
источник
Как мне получить к нему доступ в mapDispatchToProps?
Michael
2
@Michael точно так же, вы можете использовать второй аргумент
Конор Гастингс
6

При использовании машинописного текста есть несколько ошибок, поэтому вот пример.

Одна проблема заключалась в том, что когда вы используете только dispatchToProps (и не сопоставляете какие-либо свойства состояния), важно не опускать параметр состояния (его можно назвать с префиксом подчеркивания).

Еще одна проблема заключалась в том, что параметр ownProps должен был быть набран с использованием интерфейса, содержащего только переданные реквизиты - этого можно достичь, разделив интерфейс вашего реквизита на два интерфейса, например

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

Компонент можно объявить, передав единственный параметр:

<MyComponent value={event} />
Дамиан Грин
источник
1

Использование декораторов (@)

Если вы используете декораторы, в приведенном ниже коде приведен пример в случае, если вы хотите использовать декораторы для подключения redux.

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

Если вы сейчас проверите, this.props.Fooвы увидите опору, которая была добавлена ​​из того места, где использовался Barкомпонент.

<Bar Foo={'Baz'} />

В этом случае this.props.Fooбудет строка 'Baz'

Надеюсь, это проясняет некоторые вещи.

Джо Ллойд
источник