繁体   English   中英

React Native:可从每个应用程序屏幕访问的自定义组件

[英]React Native: custom component that is accessible from every app screen

什么是创建可从任何屏幕访问的自定义组件的最佳“反应”方式?

想想自定义警报component 我需要在我的应用程序的每个屏幕中,所以当出现错误时我可以显示它。

目前我这样做:

// AlertModal.js

import ... from ...;

const AlertModal = (props) => {

  const {isSuccess, headerText, bodyText, onClosed, isOpen, onBtnPress} = props;

  return (

      <Modal
        ...
        isOpen={isOpen}
        onClosed={() => onClosed()}
      >

        <View ...>

            <Text>{headerText}</Text>

          <Text>{bodyText}</Text>

          <Button
            ...
            onPress={() => onBtnPress()}
           >
              ...
           </Button>

        </View>

      </Modal>

  )
};

export default AlertModal;

//Foo.js

import ...from ...;

const Foo = (props) => {

  const { alertIsSuccess, alertHeaderText, alertBodyText, alertIsOpen, alertOnClosed, alertOnBtnPress, onBtnPress, ...rest } = props;

  return (
    <View style={}>

     ...     

      <View style={}>
        ...
      </View>


        <Button
          onPress={() => onBtnPress()}
        />

      <AlertModal
        isSuccess={alertIsSuccess}
        headerText={alertHeaderText}
        bodyText={alertBodyText}
        isOpen={alertIsOpen}
        onClosed={alertOnClosed}
        onBtnPress={alertOnBtnPress}
      />

    </View>
  )

};

export default QrCodeReader;

//FooContainer.js

import ... from ...;

class FooContainer extends Component {
    constructor(props) {
        super(props);

        this.state = {
          bar: false,
          baz: true,
          bac: '',
          bax: false,
          bav: '',

          // Alert
          alertIsOpen: false,
          alertIsSuccess: false,
          alertHeaderText: '',
          alertBodyText: '',
          alertOnClosed() {},
          alertOnBtnPress() {},
        };

      this.onBtnPress = this.onBtnPress.bind(this);
    }

    alert(isSuccess, headerText, bodyText, onBtnPress, onClosed) {

      const self = this;

      this.setState({
        alertIsOpen: true,
        alertIsSuccess: isSuccess,
        alertHeaderText: headerText,
        alertBodyText: bodyText,
        alertOnBtnPress: onBtnPress || function () { self.alertClose() },
        alertOnClosed: onClosed || function () {},
      });

    }

    alertClose() {

      this.setState({
        alertIsOpen: false,
      });

    }

    onBtnPress() {

        this.alert(
          true,
          'header text',
          'body text',
        )

    }

    render() {
        return (
          <Foo
            onBtnPress={this.onBtnPress}
            {...this.state}
          />
        );
    }
}

export default FooContainer;

你可以看到它是一种痛苦(我认为这是一种不正确的方式)。 这样做我需要在我的应用程序的每个component中包含AlertModal组件,我需要在其中显示警告=重复道具并创建新的不必要的<AlertModal />组件。

什么是正确的方法?

ps我在我的应用程序中使用react-native-router-flux作为路由器。 pss我来自Meteor.js + Cordova React-native 在那里,我可以创建一个模态并将其包含在主layout并在必要时显示/隐藏它,并在其中包含相应的动态文本。

这就是我在我的应用中导航的方式:

//Main.js
class Main extends Component {
      render() {
        return (
          <Router backAndroidHandler={() => true}>
            <Scene key="root">
              <Scene key="login" type='reset' component={SignInContainer} initial={true} hideNavBar={true}/>
              <Scene key="qrCode" type='reset' component={FooContainer} hideNavBar={true} />
            </Scene>
          </Router>
        );
      }
}

基于您使用react-native-router-flux的事实,我可以建议:

将AlertModal返回到场景组件中是自己的,不要使用Modal。 您可以通过传递属性来控制要在其中显示的内容。 将路由器中的AlertModal组件包含为“模态”架构,如下所示:

import AlertModal from '../components/AlertModal';
//Main.js
class Main extends Component {
  render() {
    return (
      <Router backAndroidHandler={() => true}>
        <Scene key="root">
          <Scene key="login" type='reset' component={SignInContainer} initial={true} hideNavBar={true}/>
          <Scene key="qrCode" type='reset' component={FooContainer} hideNavBar={true} />
          <Scene key="alertModal" duration={250} component={AlertModal} schema="modal" direction="vertical" hideNavBar={true} />
        </Scene>
      </Router>
    );
  }
}

然后你可以从任何场景调用它:

Actions.alertModal({ >optional props you want to pass< });

不确定是否有所需的行为,但这种模式可能会在Android中用后退按钮解除。 如果没有,那就有办法解决它。

这可能不是最好的解决方案,但您可以使用React的上下文功能。 本质上,传递一个函数引用,触发您的组件显示/隐藏(例如,通过将其state更改为)到上下文中。 然后,层次结构中的每个子节点都应该能够调用该函数。

但是,Facebook不鼓励使用上下文功能,并且在调试时可能会给您一些问题,因为它不像您的道具/状态那样容易跟踪。

想到的另一个解决方案可能是使用Redux,创建一个操作来更改组件订阅的属性。 然后,所有其他组件都可以dispatch该操作,更改使模式组件显示的属性的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM