R. *_*vid 5 javascript reactjs redux
如何打开一个,然后打开另一个。而且,当您单击另一个区域时,它们已关闭。
反应下拉代码:
<div className="header__nav">
<div className={classnames('header__nav__title', { 'is-active' : this.props.navAuthors })} onClick={this.props.toggleNavAuthors}><FormattedMessage {...messages.authors} /></div>
<ReactCSSTransitionGroup transitionName='header-menu-animation' transitionEnterTimeout={350} transitionLeave={false}>
{this.props.navAuthors ? this._renderAuthors() : null}
</ReactCSSTransitionGroup>
</div>
<div className="header__nav">
<div className={classnames('header__nav__title', { 'is-active' : this.props.nav })} onClick={this.props.toggleNav}><FormattedMessage {...messages.typefaces} /></div>
<ReactCSSTransitionGroup transitionName='header-menu-animation' transitionEnterTimeout={350} transitionLeave={false}>
{this.props.nav ? this._renderTypefaces() : null}
</ReactCSSTransitionGroup>
</div>
Run Code Online (Sandbox Code Playgroud)
在redux下拉代码上:
import {
SHOW_NAV,
HIDE_NAV
} from '../constants/ActionTypes'
export function toggleNav() {
return (dispatch, getState) => {
const { nav } = getState()
dispatch({
type: nav ? HIDE_NAV : SHOW_NAV
})
}
}
export function hideNav() {
return {
type: HIDE_NAV
}
}
Run Code Online (Sandbox Code Playgroud)
作为注释的状态,例如组件本地的状态可以保留在组件中。另一方面,要求在下拉列表外部单击应关闭下拉列表(或者更确切地说所有下拉列表)将再次暗示全局状态(因为它本质上是页面的属性,不再是下拉列表)。因此,正确的 redux 方法是引用商店中当前打开的下拉菜单,并在文档或窗口上设置一个重置该下拉菜单的点击处理程序。这样,任何其他下拉菜单也只会将自己设置为商店中打开的下拉菜单,自动关闭任何其他下拉菜单。
但我仍然不希望使用这种 UI 状态数据使我的商店变得过于复杂,因此我最近创建了一个 Dropdown 类,它使用本地状态和文档事件处理程序的组合来处理“任何时候只打开一个下拉列表”。这是该组件的一个非常简化的版本(也可以在这里作为fiddle获得)。
// Choose a unique name for your event, this will be listened to by
// all the dropdown components.
var EVENTNAME = "dropdown-close";
// The document triggers the event whenever anything is clicked
document.addEventListener('click', (e)=>
{
window.dispatchEvent(new CustomEvent(EVENTNAME, {
// need to pass in the original element as reference
// so the handler can check if it triggered it itself
detail: e.srcElement
}));
});
var DropDown = React.createClass({
getInitialState: function()
{
return {open: false};
},
render()
{
let menu = null;
if (this.state.open) {
menu = this.props.children;
}
return <div className="dropdown">
<a className="dropdown-toggle" ref="toggle" onClick={this.toggleMenu}>Dropdown</a>
{menu}
</div>
},
toggleMenu(e)
{
this.setState({open: !this.state.open});
},
closeMenu(e)
{
if (e.detail !== this.refs.toggle)
{
this.setState({open: false});
}
},
componentWillMount()
{
var that = this;
window.addEventListener(EVENTNAME, this.closeMenu);
},
componentWillUnmount()
{
var that = this;
window.removeEventListener(EVENTNAME, this.closeMenu);
}
});
ReactDOM.render(
<div>
<h1>First</h1>
<DropDown>
<li>Item 1 (in my case these are also React comps)</li>
<li>Item 2</li>
<li>Item 3</li>
</DropDown>
<hr/>
<h1>Second</h1>
<DropDown>
<li>Item 1 (in my case these are also React comps)</li>
<li>Item 2</li>
<li>Item 3</li>
</DropDown>
</div>,
document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud)
本质上,下拉列表根据当地状态呈现其子项。下拉开关有它自己的状态。页面上的任何点击都会触发一个事件,每个组件都会检查它是否触发了该事件本身,如果没有,它将自行关闭。