gpt4 book ai didi

javascript - ReactJS 和非分层组件

转载 作者:行者123 更新时间:2023-11-30 08:01:59 28 4
gpt4 key购买 nike

我一直在研究 ReactJS 中的上下文菜单模块,它让我开始思考如何处理非分层组件。

我遇到的问题是应用程序中的许多不同项目可能需要使用上下文菜单。通常在 React 中,您将父对象的回调传递给需要与父对象通信的子对象。例如,我的第一个想法是将 openContextMenu(mousePosition, optionsObject) 函数从我的 ContextMenu 类传递给所有想要在右侧显示上下文菜单的元素 -点击。

但是所有这些元素(甚至可能是任何元素)都是上下文菜单的子元素是没有意义的!上下文菜单相对于应用程序的其他组件不是分层的。在 Angular 中,如果组件想要访问这样的菜单,我可能会编写一个 ContextMenu 服务。

在这种情况下应该使用全局事件处理程序吗?我在想这一切都错了吗? React 如何处理组件之间的这种横向交互?

最佳答案

上下文菜单很特别。任何时候打开的上下文菜单都不应超过一个。它们也很特别,因为它可以从任何地方打开。试试 demo以了解将其放在一起时的外观。

为了解决我们的全局问题,我们将创建一个包含私有(private)事件发射器的混合。

var menuEvents = new events.EventEmitter();
var ContextMenuMixin = {
// this.openContextMenu(['foo', 'bar'], (err, choice) => void)
openContextMenu: function(options, callback){
menuEvents.emit('open', {
options: options,
callback: callback
});
},
closeContextMenu: function(){
menuEvents.emit('close');
}
};

现在对于组件,我们需要做一些事情。这是初始化部分。只需绑定(bind)一些事件,轻量级鼠标跟踪。

var mouse = {x: 0, y: 0};
var updateMouse = function(e){
mouse.x = e.pageX;
mouse.y = e.pageY;
};

var ContextMenu = React.createClass({
getInitialState: function(){
return {options: null, callback: null};
},
componentDidMount: function(){
menuEvents.addListener('open', this.handleOpenEvent);
menuEvents.addListener('close', this.closeMenu);
addEventListener('mousemove', updateMouse);
},

这些事件处理程序非常简单。 handleOpenEvent 只是将事件有效负载和鼠标位置存储在状态中,这会有效地锁定鼠标位置,直到下一次打开它。而对方只是简单地重置状态,并调用错误的回调。

 handleOpenEvent: function(payload){
this.setState(_.merge({}, payload, mouse));
},

closeMenu: function(){
if (this.state.callback) {
this.replaceState(this.getInitialState());
this.state.callback(new Error('no selection made'));
}
},

最后,我们呈现传递给事件的选项列表,并为每个选项创建点击处理程序。

render: function(){
if (!this.state.options) {
return <div />
}

var style = {
left: this.state.x,
top: this.state.y,
position: 'fixed'
};

return (
<div className="react-contextmenu" style={style}>
<ul className="react-contextmenu-options">
{this.state.options.map(function(x, i){
return <li key={i}
onClick={this.makeClickHandler(x)}>
{x}
</li>
}, this)}
</ul>
</div>
);
},

makeClickHandler: function(option){
return function(){
if (this.state.callback) {
this.state.callback(null, option);
this.replaceState(this.getInitialState());
}
}.bind(this);
}

关于javascript - ReactJS 和非分层组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25730742/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com