在 React Native 中管理多个模态的最佳实践

Best practice for managing multiple modals in React Native

我有一个屏幕,我需要在其中显示多个模式。例如,如果某个请求失败,那么我想显示一个错误模式,如果某个请求成功,那么我想显示一个成功模式。

我目前按照以下方式进行操作,我认为这是不好的做法:

...

export default function SomeSampleScreen(props) {
  const [errorModalVisible, setErrorModalVisible] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');
  const [successModalVisible, setSuccessModalVisible] = useState(false);
  const [successMessage, setSuccessMessage] = useState('');

  function showError(message) {
    setErrorMessage(message);
    setErrorModalVisible(true);
  }

  function showSuccess(message) {
    setSuccessMessage(message);
    setSuccessModalVisible(true);
  }

  return (
    <>
      <ErrorModal
        visible={errorModalVisible}
        onClose={() => {
          setErrorModalVisible(false);
        }}>
        {errorMessage}
      </ErrorModal>
      <SuccessModal
        visible={successModalVisible}
        onClose={() => {
          setSuccessModalVisible(false);
        }}>
        {successMessage}
      </SuccessModal>
      <View>
        ...
      </View>
    </>
  );
}

你可以把它压缩成一个对象:

export default function SomeSampleScreen(props) {
  const [modalState, setModalState] = useState({state: ''});

  function showError(message) {
    setModalState({state: "error", message});
  }

  function showSuccess(message) {
    setModalState({state: "success", message});
  }

  return (
    <>
      <ErrorModal
        visible={modalState.state === "error"}
        onClose={() => {
          setModalState({state: ''});
        }}>
        {modalState.message}
      </ErrorModal>
      <SuccessModal
        visible={modalState.state === "success"}
        onClose={() => {
          setModalState(false);
        }}>
        {modalState.message}
      </SuccessModal>
      <View>
        ...
      </View>
    </>
  );
}

更新 在弄清楚实际问题是什么之后,这是一个很好的方法。 创建上下文:

const ModalContext = React.createContext({status: "", message: ""});

在树中某处添加上下文和模态:

constructor(props) {
    super(props);

    this.setModal = (modalState) => {
      this.setState(state => ({...state, ...modalState}));
    };
    this.state = {
      status: "",
      message: "",
      setModal: this.setModal,
    };
  }
return <ModalContext.Provider value={this.state.modalState}>
        <RestOfApp />
        <Modals/>
      </ModalContext.Provider>

模态框与您发布的类似:

export default function SomeSampleScreen(props) {
  const modalState = useContext(ModalContext);

  function showError(message) {
    modalState.setModal({state: "error", message});
  }

  function showSuccess(message) {
    modalState.setModal({state: "success", message});
  }

  return (
    <>
      <ErrorModal
        visible={modalState.state === "error"}
        onClose={() => {
          modalState.setModal({state: ''});
        }}>
        {modalState.message}
      </ErrorModal>
      <SuccessModal
        visible={modalState.state === "success"}
        onClose={() => {
          modalState.setModal(false);
        }}>
        {modalState.message}
      </SuccessModal>
      <View>
        ...
      </View>
    </>
  );
}

您可以使用 conditional render 到 return different data on the same modal。 像这样:

export default function SomeSampleScreen(props) {
  const [ModalVisible, setModalVisible] = useState(false);
  const [errorMessage, setErrorMessage] = useState(false);
  const [successMessage, setSuccessMessage] = useState(false);

  function showError(message) {
    setErrorMessage(message);
    setModalVisible(true);
  }

  function showSuccess(message) {
    setSuccessMessage(message);
    setModalVisible(true);
  }

  return (
    <>
      <Modal
        visible={ModalVisible}
        onClose={() => {
          setSuccessModalVisible(false);
          setSuccessMessage(false);
          setErrorMessage(false);
        }}>

        {errorMessage && (
          {errorMessage}
        )}

        { successMessage && (
          {successMessage}
        )}

      </Modal>
      <View>
        ...
      </View>
    </>
  );
}