我正在努力寻找一种巧妙的方法来实现可从我的应用中的任何位置访问的模式。
我想避免在每个具有模态的组件中都有isOpen
的本地状态,因为一次只能看到一个模态。我还想避免向所有组件发送道具,因为不确定将来能够激活模态的组件。
我尝试使用Redux解决它,在我的顶级App
组件中实现基本模态组件,然后将isOpen
和component
存储在Redux中的模态子状态中,但是这样引入了很多问题,因为每次用户与模态交互时都必须更新该组件。
我也尝试使用React 16的门户网站,但它似乎不符合我的需求。帮助赞赏。这里有任何想法或最佳实践吗?
答案 0 :(得分:0)
在react-semantic-ui中查看模态的实现,modal是通过body root中的portal实例化的自我管理组件。如果你想在你的应用程序的任何地方访问它,请简单地将它引用并传递给你的compoent三。
答案 1 :(得分:0)
您已经使用的是使用Redux实现的集中状态。
使用React Baobab可能会使实现变得更加清晰,因此只有重新渲染的组件应该重新渲染。
注意:出于演示的原因,我只使用一个属性" isOpened"这与使用模态的许多组件无关。如果是这种情况,您需要在您的状态中添加其他内容,例如您要打开的模态的ID,并检查是否已设置此ID(在SomeComponent中)。
模态:
import React from "react";
export default class Modal extends React.Component {
render() {
return (
<div className="myModal"></div>
);
}
}
SomeComponent:
import React from "react";
import { branch as BaobabBranch } from "baobab-react/higher-order";
import PropTypes from "prop-types";
import { openModal } from "./actions/Modal";
@BaobabBranch({
modal: ["modal"]
})
export default class SomeComponent extends React.Component {
static propTypes = {
dispatch: PropTypes.func.isRequired,
modal: PropTypes.object.isRequired
}
onOpenModal() {
this.props.dispatch(openModal);
}
render() {
return (
<div className="someComponent">
{ this.props.modal.isOpened ?
<Modal />
:
<div class="content" onClick={::this.onOpenModal}></div>
}
</div>
);
}
}
动作/模态:
export const openModal = state => {
state.select("modal").set(Object.assign({}, state.get("modal"), {
isOpened: true
}));
};
状态:
import Baobab from "baobab";
const state = new Baobab({
modal: {
isOpened: false,
content: "someContent"
}
});
现在简短说明:
状态保存使用上述值初始化的全局状态。通过单击SomeComponent的content div,将执行openModal操作。所有行动的第一个结果始终是国家本身。一旦状态值改变,所有收听组件(通过使用@BaobabBranch)都会获得有关新道具和重新渲染的信息。
因此,如果添加其他组件,您也可以收听模态值。有了这些,您就拥有了集中模态处理所需的一切,而不是在层之间向下和向上鼓泡值。