Rekit中的UIkit模式:集成

时间:2018-03-27 11:37:29

标签: reactjs getuikit

我正在开发这个项目,其中前端是用于用户界面的UIkit的React。部件之间的集成看起来很难实现。我要解释原因。有一个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>
)

和show / hide在需要的地方以编程方式调用(甚至是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())
      }
    )
  }
}

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

任何人都可以引导我如何以更适合反应的方式整合各个部分?

2 个答案:

答案 0 :(得分:4)

使用操作dom(显示,隐藏)的uikit部分显然难以与React连接(可能你不应该),但是:

您需要通过传递模态状态的bool(例如show)来移动组件内部函数hidemodalopen的调用。一个好的钩子是componentWillReceiveProps,它可用于检查普通的道具

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

(这是在Modal类中)

答案 1 :(得分:2)

我不喜欢的东西,绝对不是&#34; React-way&#34;是代码直接从动作创建者(!)变异状态。来自React docs

  

例如,不要在a上公开open()和close()方法   对话框组件,将isOpen prop传递给它。

那么如果你有一个由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);

模态缩减器它会公开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())

当然,可能会有更多可选配置传递给动作创建者或队列模态。