React Native с реакции-навигацией и Redux - как реализовать глобально доступную кнопку «Выход» - PullRequest
0 голосов
/ 27 января 2019

Я создал приложение React Native с навигацией, предоставляемой реагировать-навигацией , также интегрируя редукс с реагировать-навигацией-редуктами-помощниками , и я пытаюсь понятьхороший способ реализации общедоступного компонента ' SignOutHeaderButton ', который при нажатии будет отправлять избыточное действие и выполнять навигационную операцию.

На данный момент у меняпередать функцию через screenProps из корневого компонента приложения, который отправляет действие приставки.Затем эта функция передается в компонент контейнера UpdatesListView через screenProps , а затем передается в общий компонент SignOutHeaderButton в качестве реквизита через navigationOptions .

Есть ли лучший способ, с помощью которого я могу реализовать это, чтобы мне не пришлось передавать какие-либо реквизиты в компонент SignOutHeaderButton и не создавать экземпляр signOut() функция внутри каждого компонента контейнера в приложении, из которого будет кнопка ' Выход '?

App.js:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { reduxifyNavigator } from 'react-navigation-redux-helpers';
import { PersistGate } from 'redux-persist/integration/react';
import { Provider, connect } from 'react-redux';

import { appContainer } from './src/navigators';
import { store, persistor } from './src/store/configureStore';
import { signOut } from './src/actions/auth';

const app = reduxifyNavigator(appContainer, 'root');

const mapStateToProps = state => {
  return {
        state: state.navReducer
  }
}

const AppWithNavigationState = connect(mapStateToProps)(app);

export default class App extends React.Component {

  signOut() {
    store.dispatch(signOut());
  }

  render() {
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <AppWithNavigationState
            screenProps={{
              signOut: this.signOut
                }} />
        </PersistGate>
      </Provider>
    )
  }
}

UpdatesListView.js:

import React from 'react';
import { View, Container, Content, Text, Button } from 'native-base';
import { connect } from 'react-redux';

import SignOutHeaderButton from '../components/common/SignOutHeaderButton';

class UpdatesListView extends React.Component {

  constructor(props) {
    super(props);
  }

  static navigationOptions = ({ navigation }) => {
    return {
      headerTitle: 'Updates',
      headerRight: <SignOutHeaderButton signOut={navigation.getParam('signOut')} />
    }
  }

  componentDidMount() {
    this.props.navigation.setParams({
      signOut: this.props.screenProps.signOut
    })
  }

  render() {
    return (
      <Container>
        <Text>UpdatesListView</Text>
      </Container>
    )
  }
}


const mapStatetoProps = state => {
  return {
        updates: state.updatesReducer,
        tags: state.tagsReducer
  }
}

export default connect(mapStateToProps)(UpdatesListView);

SignOutHeaderButton.js:

import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';

class SignOutHeaderButton extends React.Component {

  constructor(props) {
    super(props);
  }

  signOut() {
    this.props.signOut();
    this.props.navigation.navigate('AuthStack');
  }

  render() {
    return (
      <Button
        title="Sign Out"
        onPress={this.signOut} />
    )
  }
}

export default withNavigation(SignOutHeaderButton);

1 Ответ

0 голосов
/ 27 января 2019

Используйте соединение с резервированием, идея соединения с резервированием состоит в том, чтобы связать store dispatch state с вашим компонентом this. При использовании соединения с резервированием вы можете получить доступ к любому магазину резервирования dispatch и stateиз любого места в вашем приложении это работает как по реагированию, так и по собственному реагированию, например, для SignOutHeaderButton.js:

import React from 'react';
import { Button } from 'react-native';
import { connect } from 'react-redux';
import { withNavigation } from 'react-navigation';

class SignOutHeaderButton extends React.Component {

  constructor(props) {
    super(props);
  }

  signOut() {
    this.dispatch(signOut());
    this.props.navigation.navigate('AuthStack');
  }

  render() {
    return (
      <Button
        title="Sign Out"
        onPress={this.signOut} />
    )
  }
}

export default connect()(withNavigation(SignOutHeaderButton));

Кроме того, вы можете передать состояние хранилища избыточности в свой компонент следующим образом:передача функции в connect(/*your function*/) для разрешения данных состояния, которые вы хотите.для лучшего понимания вы можете попробовать этот учебник: https://blog.logrocket.com/react-redux-connect-when-and-how-to-use-it-f2a1edab2013

Примечание Использование вложенных интеллектуальных компонентов очень распространено, у redux connect есть очень умный алгоритм для сравнения изменений состояния магазина, пожалуйста, проверьтеэто: https://hackernoon.com/why-using-nested-connect-react-redux-components-is-good-bd17997b53d2 enter image description here

...