我正在开发这个项目,其中前端是用于用户界面的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())
}
)
}
}
这似乎有效。直到你离开组件。当你回到它时,第二次以编程方式隐藏它不再起作用。
任何人都可以引导我如何以更适合反应的方式整合各个部分?
答案 0 :(得分:4)
使用操作dom(显示,隐藏)的uikit部分显然难以与React连接(可能你不应该),但是:
您需要通过传递模态状态的bool(例如show
)来移动组件内部函数hide
和modalopen
的调用。一个好的钩子是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())
当然,可能会有更多可选配置传递给动作创建者或队列模态。