Мне нужно показать / скрыть модальное окно на основе взаимодействия с пользователем (т.е. нажатие кнопки) в компоненте, который не является ни родительским, ни дочерним для самого модального окна. В настоящее время я пытаюсь сделать это, передав модальное окно в качестве опоры модальному контроллеру, но в зависимости от того, какой метод я вызываю, возникают следующие ошибки:

  • TypeError: modal.setNativeProps не является функцией
  • TypeError: modal.setState не является функцией

Есть ли способ показать модальное окно с учетом его структуры?


import Modal from 'react-native-modal'

const modalRef = React.createRef();
const modal = <Modal ref={modalRef} isVisible={false}>

<ModalController modal={modalRef} />

export const ModalController = ({modal}) => {

 function onButtonPress(){
   modal.setState({isVisible:true})
   modal.setNativeProps({isVisible:true})
 }

 return (
  <Button title='Show Modal' onPress={onButtonPress()} />
 )

}

0
user3495491 28 Июл 2020 в 23:39

2 ответа

Лучший ответ

Думаю, вы немного запутались.

Во-первых, помните, что все внутри ModalController будет выполняться при каждой визуализации. Ваша функция onButtonPress будет создаваться при каждом рендеринге (это нормально), но на самом деле вы вызываете эту функцию, когда передаете ее в onPress рендер. Это означает, что вы выполняете onButtonPress при каждом рендеринге, что, вероятно, не то, что вам нужно.

Это простое решение - просто удалите (), и останется только onPress={onButtonPress}. Теперь он срабатывает только при нажатии кнопки.

По сути, решение вашей проблемы намного проще, чем то, что вы сделали в своем коде. Обычно «refs» используются только в особых случаях, когда вы действительно хотите указать своим компонентам, что делать (например, указание ScrollView прокрутить до определенной позиции или указание ввода для фокусировки, чтобы отображалась клавиатура). Если вы используете ссылку, это должно быть сделано намеренно.

Таким образом, простое решение иметь компонент с кнопкой, которая показывает модальное окно, может выглядеть так:

import React, {useState} from 'react';
import {View, Button, Text} from 'react-native';
import Modal from 'react-native-modal';

export const ModalController = () => {
  const [isModalVisible, setIsModalVisible] = useState(false);

  function onButtonPress() {
    setIsModalVisible(true);
  }

  return (
    <View>
      <Button title='Show Modal' onPress={onButtonPress} />
      {isModalVisible && <MyModal />}
    </View>
  );
};

const MyModal = () => (
  <Modal>
    <Text>Hey I am a modal</Text>
  </Modal>
);

Обратите внимание на использование useState. Вот как вы удерживаете «состояние» в таком функциональном компоненте (в отличие от компонента класса, в котором вы бы использовали setState.

Надеюсь, это поможет. Дайте мне знать, если у вас есть вопросы!

0
James 28 Июл 2020 в 21:05

Чао, в случае, если между компонентами нет отношений родитель / потомок, я нашел единственный способ передавать / устанавливать данные от одного компонента к другому - использовать глобальный менеджер состояний, например react-redux. С помощью redux вы можете легко определить глобальное состояние и установить его из компонента, запускающего модальное открытие / закрытие. Модальный компонент считывает это состояние и сам открывает / закрывает.

1
Giovanni Esposito 28 Июл 2020 в 21:00