【问题标题】:UIkit's modals in React: integrationReact 中 UIkit 的模态:集成
【发布时间】:2018-09-05 19:16:51
【问题描述】:

我正在做这个项目,其中前端在 React 中与 UIkit 一起用于用户界面。各部分之间的集成看起来执行得很差。我将解释为什么。有一个Modal 组件,类似于

export class Modal extends Component {
  static getByName = name => UIkit.modal(`[data-modal-name='${name}']`)

  static show = name => {
    const modal = Modal.getByName(name)
    if (modal) modal.show()
  }

  static hide = name => {
    const modal = Modal.getByName(name)
    if (modal) modal.hide()
  }

  render() {
    // a modal
  }
}

这是这样使用的

export const LoginFormModal = props => (
  <Modal name="login-form" className="login-form-modal" hideClose>
    <LoginForm />
  </Modal>
)

并在需要时以编程方式调用显示/隐藏(甚至是 redux 的操作)

Modal.hide("login-form")

这是在 Redux 操作中,像这样

export const login = credentials => {
  return dispatch => {
    dispatch(showLoader())

    API.authentication.login(
      credentials,
      response => {
        setCurrentUser(
          Object.assign({}, response.user, { user_id: response.user.id })
        )
        Modal.hide("login-form")
        dispatch(loginSucceded(response))
        dispatch(hideLoader())
        dispatch(push("/"))
        dispatch(fetchNotificationsCounter())
      },
      error => {
        dispatch(loginFailed(error))
        dispatch(hideLoader())
      }
    )
  }
}

这似乎有效。直到你离开一个组件。当你回到它时,第二次以编程方式隐藏不再起作用。

任何人都可以指导我如何以更适合反应的方式集成这些部分?

【问题讨论】:

  • redux state 可以用这个吗?你能在你的 redux 操作中添加代码示例吗?
  • 添加了一个redux动作作为例子
  • 它第一次工作,我的模态以编程方式关闭。但是,如果我离开组件(卸载)并返回它,就再也不会工作了。
  • 您必须获得表明您已在LoginFormModal登录的状态

标签: reactjs getuikit


【解决方案1】:

使用 uikit 中操纵 dom(显示、隐藏)的部分显然很难与 React 连接(可能你不应该这样做),但是:

您需要通过传递模态状态的布尔值(例如modalopen)来移动组件内部函数showhide 的调用。一个很好的钩子是componentWillReceiveProps,它可以用来检查previus props

componentWillReceiveProps(nextProps) {
  if (nextProps.modalopen !== this.props.modalopen) {
    if (nextProps.modalopen) {
      getByName(...).show()
    } else {
      getByName(...).hide()
    }
  }
}

(这是在 Modal 类中)

【讨论】:

  • 您可能会为您加载的内容做类似的事情(假设基于调度程序中的showLoaderhideLoader
【解决方案2】:

我不喜欢并且绝对不是“React 方式”的事情是代码直接从动作创建者 (!) 改变状态。来自React docs

例如,而不是将 open() 和 close() 方法暴露在 对话框组件,传递一个 isOpen 属性给它。

那么,如果你有一个由 redux 状态控制的模态呢?这是一个可能的实现:

ModalWindow - 将对状态变化做出反应并根据存储的内容进行渲染:

import React from 'react';
import InfoContent from './InfoContent';
import YesOrNoContent from './YesOrNoContent';
import { MODAL_ACTION } from './modal/reducer';

class ModalWindow extends React.Component {
  renderModalTitle = () => {
    switch (this.props.modalAction) {
        case MODAL_ACTION.INFO:
          return 'Info';
        case MODAL_ACTION.YES_OR_NO:
          return 'Are you sure?';
        default:
          return '';
    }
  };

  renderModalContent = () => {
    switch (this.props.modalAction) {
      case MODAL_ACTION.INFO:
        return <InfoContent />;
      case MODAL_ACTION.YES_OR_NO:
        return <YesOrNoContent />;
      default:
        return null;
    }
  };

  render() {
    return (
        this.props.isModalVisible ?
        <div>
           <p>{this.renderTitle()}</p> 
           <div>
              {this.renderModalContent()}
           </div>
        </div>
        :
        null
    );
  }
}

export default connect((state) => ({
    modalAction: state.modal.modalAction,
    isModalVisible: state.modal.isModalVisible,
}))(ModalWindow);

modal reducer 它将暴露 API 以在应用程序中显示/隐藏模式窗口:

export const SHOW_MODAL = 'SHOW_MODAL';
export const HIDE_MODAL = 'HIDE_MODAL';

const INITIAL_STATE = {
  isModalVisible: false,
  modalAction: '',
};

export default function reducer(state = INITIAL_STATE, action) {
  switch (action.type) {
    case SHOW_MODAL:
      return { ...state, isModalVisible: true, modalAction: action.modalAction };
    case HIDE_MODAL:
      return { ...state, isModalVisible: false };
    default:
      return state;
  }
}

export const MODAL_ACTION = {
  YES_OR_NO: 'YES_OR_NO',
  INFO: 'INFO',
};

const showModal = (modalAction) => ({ type: SHOW_MODAL, modalAction });
export const hideModal = () => ({ type: HIDE_MODAL });
export const showInformation = () => showModal(MODAL_ACTION.INFO);
export const askForConfirmation = () => showModal(MODAL_ACTION.YES_OR_NO);

所以基本上你以 redux action-creators 的形式公开简单的 API 来控制 ModalWindow 的状态。您以后可以使用如下:

dispatch(showInformation())
...
dispatch(hideModal())

当然,它还可以有更多可选配置,例如传递给动作创建者或模式队列的可选配置。

【讨论】:

    猜你喜欢
    • 2011-07-30
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    相关资源
    最近更新 更多