如何将React Native自定义警报作为函数调用?

t5zmwmid  于 2023-06-24  发布在  React
关注(0)|答案(5)|浏览(142)

我正在开发一个React Native应用程序。我使用modal创建了自己的自定义alert作为component。当我使用它时,我总是需要在我的render()函数中添加我的alert组件。
有没有什么方法可以使用自定义警报,而不用在我的render()函数中渲染它?
我的意思是,我可以在react-native中使用Alert,将其称为Alert.alert()。我想用我自己的自定义警报也一样。
我该怎么做?

kx5bkwkv

kx5bkwkv1#

你能做到的

class SomeComponent extends Component {
  static myComponentInstance

  constructor(props) {
    super(props)

    this.state = {
      visible: false,
      text: ""
    }

    SomeComponent.myComponentInstance = this
  }

  static show(text) {
    SomeComponent.myComponentInstance._show(text)
  }

  _show(text) {
    this.setState({ visible: true, text })
  }

  render(){
    return (
      <Modal visible={this.state.visible}>
        <Text>{this.state.text}</Text>
      </Modal>
    )
  }
}

const AppRoot = () => (
  <View>
    <Navigator />
    <SomeComponent/>
  </View>
)

为了展示你可以在任何地方做SomeComponent.show("some text")

5q4ezhmt

5q4ezhmt2#

使方法保持静态。

class MyCustomAlert extends React.Component {
  static alert () {
  }
}

用法

import MyCustomAlert from './MyCustomAlert';

MyCustomAlert.alert()
qoefvg9y

qoefvg9y3#

Alert.alert()调用本机代码。如果要显示自定义警报组件,则需要将其添加到渲染方法中。最简单的方法是将它放在根组件或其他父组件中。
设置要有条件显示的元件。创建一个方法来设置条件。可以将此方法传递给子组件。

this.alertToggle = (displayAlert) => this.setState({displayAlert});

render(){
  return (
      <Parent>
        {this.state.displayAlert && <CustomAlert/>}
        <Child alertToggle={this.alertToggle}
      </Parent>
    )
}

您可以调用this.props.alertToggle(true)来显示父级中的警报组件。
EDIT:由于您使用modal创建了组件,因此可以将display布尔值传递给CustomAlert组件,并在组件中触发modal。<CustomAlert displayAlert={this.state.displayAlert} />将自定义警报放在父级中的想法是相同的。

fhg3lkii

fhg3lkii4#

您也可以使用此API react-native-popup-dialog来设计您的警报。
我个人是这么做的:

...
  <Dialog
  visible={this.props.visible}>
    <DialogContent>
      <View style={ container }>
        <Text style={ title }> { this.props.title } </Text>
        <Text style={ text }> { this.props.text } </Text>
        <View style={ buttonView }>
          <TouchableOpacity style={ button } onPress={ this.props.validationAction }>
            <Text style={ buttonText }>{ this.props.validationText }</Text>
          </TouchableOpacity>
        </View>
      </View>
    </DialogContent>
  </Dialog>
  ...

家长:

<Alert
visible={ this.state.visible }
title={ "Alert title" }
text={ "This is an custom alert." }
validationText={ "OK" }
validationAction={ () =>  {
  this.setState({ visible: false });
}} />

我希望这会有所帮助。

vzgqcmou

vzgqcmou5#

正如我所理解的,你希望你的模态以无状态的方式处理。遗憾的是,没有渲染Modal是无法做到的,但是你可以在应用渲染树之外添加一个虚拟div并在函数调用中使用渲染来操纵它的dom。

function modalHandler(CustomModal) {
  const div = document.createElement("div");
  this.hide = () => {
    ReactDOM.unmountComponentAtNode(div);
    div.remove();
  };
  this.show = props => {
    document.body.appendChild(div);
    ReactDOM.render(<CustomModal onRequestClose={this.hide} {...props} />, div);
  };

  return {
    show: this.show,
    hide: this.hide,
  };
}

然后用handler为modal创建示例:

const myModal = new modalHandler(CustomModal);

然后,你可以在任何你喜欢的地方使用调用,而不会扰乱应用的渲染树:

myModal.show()
myModal.hide()

示例:

const modalStyle = { content: { top: '50%',left: '50%', right: 'auto', bottom: 'auto', marginRight: '-50%', transform: 'translate(-50%, -50%)'}};

const CustomModal = ({ onRequestClose, ...props }) => (
  <ReactModal {...props} isOpen={true} contentLabel="CustomModal" >
    <h1>This modal will close in 3 seconds</h1>
    <button onClick={onRequestClose}>Close</button>
  </ReactModal>
);

// Create Stateless Modal handler from component with HOF
function modalHandler(CustomModal) {
  const div = document.createElement("div");
  this.callOnHide = () => {};
  this.callOnShow = () => {};
  this.hide = () => {
  	this.callOnHide();
    ReactDOM.unmountComponentAtNode(div);
    div.remove();
  };
  this.show = props => {
  	this.callOnShow();
    document.body.appendChild(div);
    ReactDOM.render(<CustomModal onRequestClose={this.hide} {...props} />, div);
  };

  return {
    show: this.show,
    hide: this.hide,
    setOnHideCallback: callback => {
      this.callOnHide = callback;
    },
    setOnShowCallback: callback => {
      this.callOnShow = callback;
    }
  };
}

// Create instance from modal component
const myModal = new modalHandler(CustomModal);

class View extends React.Component {
  openModalHandler = () => {
    myModal.show();

    // auto close in 3 second
    const timer = setTimeout(() => {
      myModal.hide();
    }, 3000);

		// clear the timeout onHide
    myModal.setOnHideCallback(()=>{
    	clearTimeout(timer)
    })
  };

  render() {
    return (
      <div>
        <button onClick={this.openModalHandler}>Open modal</button>
      </div>
    );
  }
}

ReactDOM.render(<View />, document.getElementById("root"));
<script src="https://unpkg.com/react@0.14.0/dist/react-with-addons.js">
</script>
<script src="https://unpkg.com/react-dom@0.14.0/dist/react-dom.js">
</script>
<script src="https://unpkg.com/react-modal@1.6.2/dist/react-modal.min.js">
</script>

<div id="root">
</div>

相关问题