最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to call React Native custom alert as a function? - Stack Overflow

programmeradmin1浏览0评论

I'm developing a React Native app. I created my own custom alert as a ponent using modal. When I use it, I always need to add my alert ponent in my render() function.

Is there any way to use the custom alert without rendering it inside my render() function?

I mean, I can use Alert in react-native by calling it as Alert.alert(). I want to use my own custom alert also like that.

How can I do that?

I'm developing a React Native app. I created my own custom alert as a ponent using modal. When I use it, I always need to add my alert ponent in my render() function.

Is there any way to use the custom alert without rendering it inside my render() function?

I mean, I can use Alert in react-native by calling it as Alert.alert(). I want to use my own custom alert also like that.

How can I do that?

Share Improve this question asked Jun 3, 2019 at 9:16 Sennen RandikaSennen Randika 1,6463 gold badges17 silver badges35 bronze badges 2
  • Have you written any code where you've tried to solve this? Please, add it in your question – Samuli Hakoniemi Commented Jun 3, 2019 at 9:18
  • This will help you github./facebook/react-native/blob/master/Libraries/Alert/… – Rajendran Nadar Commented Jun 3, 2019 at 9:24
Add a ment  | 

5 Answers 5

Reset to default 2

You could do this

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

And to show it you can do anywhere SomeComponent.show("some text")

Make the method static.

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

usage

import MyCustomAlert from './MyCustomAlert';

MyCustomAlert.alert()

Alert.alert() calls native code. If you want to display your custom alert ponent, you'll need to add it to your render method. It would be easiest to put it in your root or some other parent ponent.

Set the ponent to be displayed conditionally. Create a method to set the condition. You can pass this method down to your child ponents.

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

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

You can call this.props.alertToggle(true) to display the alert ponent in the parent.

EDIT: Since you made the ponent using modal, you could pass the display boolean to the CustomAlert ponent, and trigger the modal within the ponent. <CustomAlert displayAlert={this.state.displayAlert} /> The idea of putting the custom alert in the parent is the same.

You can also use this API react-native-popup-dialog to design your alert.

Personnaly I did something like that:

  ...
  <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>
  ...

And the parent:

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

I hope it will help.

As i understood, you want your modal to be handled stateless way. Sadly there is no way to do it without Modal being rendered, buuuut you can do it apart from your app render tree by appending a dummy div and manipulate its dom with render inside your function call.

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,
  };
}

And then create instance for your modal with handler :

const myModal = new modalHandler(CustomModal);

Then you can use your calls anywhere you like without messing your app's render tree:

myModal.show()
myModal.hide()

Example:

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 ponent 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 ponent
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./[email protected]/dist/react-with-addons.js">
</script>
<script src="https://unpkg./[email protected]/dist/react-dom.js">
</script>
<script src="https://unpkg./[email protected]/dist/react-modal.min.js">
</script>

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

发布评论

评论列表(0)

  1. 暂无评论