Реагировать на изменение состояния родительского / дочернего элемента Вопрос о дизайне

#javascript #reactjs #react-native #parent-child #react-native-modal

#javascript #reactjs #реагировать — родной #родитель-потомок #реагировать-собственный-модальный

Вопрос:

У меня есть компонент с двумя дочерними элементами, один из них — это кнопка, которая переключает состояние (modalVisible), которое решает, виден ли другой дочерний элемент, модальный.

У меня возникли проблемы с разделением состояния включения / выключения между родительским и модальным дочерним элементами. Я попытался сохранить состояние в родительском элементе, а затем передать его в качестве опоры дочернему элементу, но он не повторял дочерний элемент каждый раз, когда менялось родительское состояние.

 <CommentsModal visible={modalVisible} />
  

Внутри CommentsModal.js …

 import Modal from 'react-native-modal';
...
const CommentsModal = ({visible}) => {
    const [modalVisible, setModalVisible] = useState(visible);
    ...
    return <Modal visible={modalVisible} />
}
  

Я рассматривал возможность сохранения состояния полностью в родительском, не передавая его в CommentsModal, например:

 function renderModal() {
    if (modalVisible) {
        return <CommentsModal visible={true} />
    } else {
        return <View />
    }
}
  

Но я понял, что внутри CommentsModal должно быть состояние, потому что мне нужна кнопка «X», которая отключает модальное отключение.

Я не уверен, какой лучший способ сделать это… Я мог бы сделать redux, но поскольку существует динамическое число этих модальностей; Я не хочу, чтобы мой магазин был таким сложным. Единственный способ, о котором я могу думать, — это переместить весь модальный код в родительский компонент, тогда они могут легко обмениваться состояниями, но мне это кажется грязным. У кого-нибудь есть решение?

Ответ №1:

Ваша интуиция, чтобы сохранить состояние в родительском компоненте, верна. Для реализации кнопки x все, что вам нужно, это передать onClose prop модальному, который будет функцией, для которой установлено modalVisible значение false. итак, в итоге вы получите что-то вроде этого:

 // parent component
const ParentComponent = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const openModal = () => setModalVisible(true);
  const closeModal = () => setModalVisible(false);

  return (
    <div>
      <CommentsModal visible={modalVisible} onClose={closeModal} />
      <button onClick={openModal}>open the modal</button>
      <p>other children here...</p>
    </div>
  )
}


// CommentsModal
const CommentsModal = (props) => (
  <Modal visible={props.visible}>
    <button onClick={props.onClose}>X</button>
    <p>more modal content here...</p>
  </Modal>
)
  

Комментарии:

1. очевидно, вам нужно будет заменить divs на views, button на touchableopacity и т. Д. Но Это тот же принцип, что и в react amp; react native.

2. Я не знаю, почему я думал, что это не сработает. Я помню, как раньше сталкивался с ошибкой, в которой говорилось, что вы не можете изменить состояние внутри другого компонента. Вероятно, это означало что-то другое. Спасибо!