带有react-navigation和Redux的React Native-如何实现全局可用的“退出”按钮

时间:2019-01-27 18:41:21

标签: javascript react-native redux react-redux react-navigation

我已经创建了一个具有 react-navigation 提供的导航功能的React Native应用程序,还将redux与 react-navigation-redux-helpers 集成在一起,我正在尝试找出实现全局可用的' SignOutHeaderButton '组件的好方法,该组件在按下时将调度redux动作并执行导航操作。

此刻,我必须通过 screenProps 从应用程序根组件传递一个函数,该函数是调度redux动作的函数。然后,该函数通过 screenProps 传递给 UpdatesListView 容器组件,然后作为道具通过传递给 SignOutHeaderButton 通用组件。 navigationOptions

有没有更好的方法可以实现此目的,这样我就不必将任何道具传递到 SignOutHeaderButton 组件中,而不必实例化 signOut()函数都有一个 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 :(得分:1)

使用redux connect,redux connect的想法是将store dispatch state绑定到组件this,当您使用redux connect时,您可以访问任何redux从应用程序中的任何位置存储dispatchstate,这既适用于react也适用于react-native,例如用于 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*/)来解析所需的状态数据,从而将redux存储状态传递给组件。 为了更好地理解,您可以尝试以下教程: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