为什么 react-single-page-navigation 只能在没有构造函数和状态的组件中工作?
Why is react-single-page-navigation only working in Components without constructor and state?
我目前正在学习 React,我发现了这个很酷的包:https://www.npmjs.com/package/react-single-page-navigation。
我开始使用它,一切顺利。然后我想让我的网络应用程序响应,所以我为小屏幕构建了一个移动导航(简单的下拉菜单)。
首先,这个导航也很管用!下拉列表始终显示,我可以点击按钮及其参考,然后通过平滑滚动导航到所需的部分。
由于下拉菜单的显示和隐藏功能,我向移动导航组件添加了一个带有状态 menuVisible 的构造函数,并添加了两个函数来处理“打开下拉菜单”按钮上的点击以及除下拉项目之外的任何其他地方的点击(标准下拉机制)。
这个机制运作良好,dropdwon 看起来不错。但是:导航不再起作用。相反,我总是在我的网络应用程序的第一部分上下“导航”一些像素。
这是可用的桌面导航组件:
import React, {Component} from 'react';
export default class DesktopNavigation extends Component {
render() {
return (
<nav className={this.props.sticky ? 'navbar navbar--sticky' : 'navbar'} id='mainNav'>
<div className='navbar--logo-holder'>
<img alt='logo' className='navbar--logo'/>
<h1 className={this.props.sticky ? 'navbar--logo-text-sticky' : 'navbar--logo-text'}>Booyar</h1>
</div>
<ul className='navbar--link'>
<div ref={this.props.refs.Home} onClick={() => this.props.goTo('Home')}>
<div className={(this.props.activeElement === 'Home' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Home
</div>
</div>
<div ref={this.props.refs.About} onClick={() => this.props.goTo('About')}>
<div className={(this.props.activeElement === 'About' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
About
</div>
</div>
<div ref={this.props.refs.Services} onClick={() => this.props.goTo('Services')}>
<div className={(this.props.activeElement === 'Services' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Services
</div>
</div>
<div ref={this.props.refs.Projects} onClick={() => this.props.goTo('Projects')}>
<div className={(this.props.activeElement === 'Projects' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Projects
</div>
</div>
<div ref={this.props.refs.Contact} onClick={() => this.props.goTo('Contact')}>
<div className={(this.props.activeElement === 'Contact' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Contact
</div>
</div>
</ul>
</nav>
);
}
}
以下是无法正常工作的移动导航组件:
import React, {Component} from 'react';
import DropdownMenu from "./dropdownMenu";
export default class MobileNavigation extends Component {
constructor(props) {
super(props);
this.state = {
sticky: this.props.sticky
}
}
callbackIsSticky = (isSticky) => {
this.setState({sticky: isSticky})
}
render() {
return (
<nav className={this.state.sticky || this.props.sticky ? "mobile-navbar mobile-navbar-sticky" : "mobile-navbar"} id="mainNav">
<div className="mobile-navbar--logo-holder">
<img alt="logo" className="mobile-navbar--logo"/>
</div>
<DropdownMenu
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.sticky}
callback={this.callbackIsSticky}
/>
</nav>
);
}
}
import React, {Component} from 'react';
/**
* This class represents the dropdown menu in mobile view.
*/
export default class DropdownMenu extends Component {
constructor(props) {
super(props);
this.state = {
menuVisible: false
}
this.handleClick = this.handleClick.bind(this);
this.handleOutsideClick = this.handleOutsideClick.bind(this);
}
handleClick() {
if (!this.state.menuVisible) {
document.addEventListener('click', this.handleOutsideClick, false);
this.props.callback(true);
} else {
document.removeEventListener('click', this.handleOutsideClick, false);
this.props.callback(false);
}
this.setState(stateBefore => ({
menuVisible: !stateBefore.menuVisible,
}));
}
handleOutsideClick(event) {
if (this.node.contains(event.target)) {
return;
}
this.handleClick();
}
render() {
const items =
<div className={'dropdown-items'}>
<button
ref={this.props.refs.Home} onClick={() => this.props.goTo('Home')}
className={(this.props.activeElement === 'Home' ? "active-mobile-page " : "")}>
Home
</button>
<button
ref={this.props.refs.About} onClick={() => this.props.goTo('About')}
className={(this.props.activeElement === 'About' ? "active-mobile-page " : "")}>
About
</button>
<button
ref={this.props.refs.Services} onClick={() => this.props.goTo('Services')}
className={(this.props.activeElement === 'Services' ? "active-mobile-page " : "")}>
Services
</button>
<button
ref={this.props.refs.Projects} onClick={() => this.props.goTo('Projects')}
className={(this.props.activeElement === 'Projects' ? "active-mobile-page " : "")}>
Projects
</button>
<button
ref={this.props.refs.Contact} onClick={() => this.props.goTo('Contact')}
className={(this.props.activeElement === 'Contact' ? "active-mobile-page " : "")}>
Contact
</button>
</div>;
return (
<div className={'dropdown-menu' + (this.state.menuVisible ? ' dropdown-menu-open' : '')}
ref={node => this.node = node}>
<button className={'hamburger hamburger--elastic' + (this.state.menuVisible ? ' is-active' : '')} onClick={this.handleClick} type={'button'}>
<span className="hamburger-box">
<span className={'hamburger-inner' + (this.state.menuVisible || this.props.sticky ? ' hamburger-inner-sticky' : '')}>
</span>
</span>
</button>
{this.state.menuVisible ? items : undefined}
</div>
);
}
}
当然,一切都被 <ScrollNavigation elements={{Home: {}, About: {}, Services: {}, Projects: {}, Contact: {}}}>...</ScrollNavigation>
包装起来,如 react-single-page-navigation 的文档所述。
我决定是显示移动导航还是桌面导航 css 以及以下 class:
import React, {Component} from 'react';
import MobileNavigation from "./mobileNavigation";
import DesktopNavigation from "./desktopNavigation";
export default class Navigation extends Component {
render() {
return (
<div>
<MobileNavigation
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.isSticky}/>
<DesktopNavigation
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.isSticky}/>
</div>
);
}
}
我希望这些信息足够了。我不喜欢 post 我的整个项目,但我认为这是没有必要的。桌面导航按预期工作。移动导航仅在主页部分导航毫米。我认为有一个基本的反应“东西”导致了我无法弄清楚的行为,因为当我取消注释除了渲染方法之外的所有东西时移动导航工作(以及调用未注释的东西的渲染方法中的东西;)) .
如果您需要更多信息或有其他问题,请提问! :)
提前致谢,节日快乐!
马克西莫图斯
好的,所以我的错误是将滚动导航 ref={this.props.refs.Home}
(等)的引用放到了按钮上。我不知何故误解了 instructions in the docs of react-single-page-navigation。 ref 属性就像 'anchor' 所以滚动导航知道滚动到哪里。我将这个 ref 添加到按钮本身,所以导航只是滚动到按钮的位置。
所以我只是将它从按钮中删除,现在一切正常(桌面导航也一样,我知道为什么它以前在那里工作但出现同样的错误)。
<ul className='navbar--link'>
<div onClick={() => this.props.goTo('Home')}>
<div
className={(this.props.activeElement === 'Home' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Home
</div>
</div>
<div onClick={() => this.props.goTo('About')}>
<div
className={(this.props.activeElement === 'About' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
About
</div>
</div>
<div onClick={() => this.props.goTo('Services')}>
<div
className={(this.props.activeElement === 'Services' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Services
</div>
</div>
<div onClick={() => this.props.goTo('Projects')}>
<div
className={(this.props.activeElement === 'Projects' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Projects
</div>
</div>
<div onClick={() => this.props.goTo('Contact')}>
<div
className={(this.props.activeElement === 'Contact' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Contact
</div>
</div>
</ul>
现在,滚动导航的触发器只定义了 goTo 属性,而 ref 属性由我网站的部分定义。
我目前正在学习 React,我发现了这个很酷的包:https://www.npmjs.com/package/react-single-page-navigation。
我开始使用它,一切顺利。然后我想让我的网络应用程序响应,所以我为小屏幕构建了一个移动导航(简单的下拉菜单)。
首先,这个导航也很管用!下拉列表始终显示,我可以点击按钮及其参考,然后通过平滑滚动导航到所需的部分。 由于下拉菜单的显示和隐藏功能,我向移动导航组件添加了一个带有状态 menuVisible 的构造函数,并添加了两个函数来处理“打开下拉菜单”按钮上的点击以及除下拉项目之外的任何其他地方的点击(标准下拉机制)。
这个机制运作良好,dropdwon 看起来不错。但是:导航不再起作用。相反,我总是在我的网络应用程序的第一部分上下“导航”一些像素。
这是可用的桌面导航组件:
import React, {Component} from 'react';
export default class DesktopNavigation extends Component {
render() {
return (
<nav className={this.props.sticky ? 'navbar navbar--sticky' : 'navbar'} id='mainNav'>
<div className='navbar--logo-holder'>
<img alt='logo' className='navbar--logo'/>
<h1 className={this.props.sticky ? 'navbar--logo-text-sticky' : 'navbar--logo-text'}>Booyar</h1>
</div>
<ul className='navbar--link'>
<div ref={this.props.refs.Home} onClick={() => this.props.goTo('Home')}>
<div className={(this.props.activeElement === 'Home' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Home
</div>
</div>
<div ref={this.props.refs.About} onClick={() => this.props.goTo('About')}>
<div className={(this.props.activeElement === 'About' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
About
</div>
</div>
<div ref={this.props.refs.Services} onClick={() => this.props.goTo('Services')}>
<div className={(this.props.activeElement === 'Services' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Services
</div>
</div>
<div ref={this.props.refs.Projects} onClick={() => this.props.goTo('Projects')}>
<div className={(this.props.activeElement === 'Projects' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Projects
</div>
</div>
<div ref={this.props.refs.Contact} onClick={() => this.props.goTo('Contact')}>
<div className={(this.props.activeElement === 'Contact' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Contact
</div>
</div>
</ul>
</nav>
);
}
}
以下是无法正常工作的移动导航组件:
import React, {Component} from 'react';
import DropdownMenu from "./dropdownMenu";
export default class MobileNavigation extends Component {
constructor(props) {
super(props);
this.state = {
sticky: this.props.sticky
}
}
callbackIsSticky = (isSticky) => {
this.setState({sticky: isSticky})
}
render() {
return (
<nav className={this.state.sticky || this.props.sticky ? "mobile-navbar mobile-navbar-sticky" : "mobile-navbar"} id="mainNav">
<div className="mobile-navbar--logo-holder">
<img alt="logo" className="mobile-navbar--logo"/>
</div>
<DropdownMenu
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.sticky}
callback={this.callbackIsSticky}
/>
</nav>
);
}
}
import React, {Component} from 'react';
/**
* This class represents the dropdown menu in mobile view.
*/
export default class DropdownMenu extends Component {
constructor(props) {
super(props);
this.state = {
menuVisible: false
}
this.handleClick = this.handleClick.bind(this);
this.handleOutsideClick = this.handleOutsideClick.bind(this);
}
handleClick() {
if (!this.state.menuVisible) {
document.addEventListener('click', this.handleOutsideClick, false);
this.props.callback(true);
} else {
document.removeEventListener('click', this.handleOutsideClick, false);
this.props.callback(false);
}
this.setState(stateBefore => ({
menuVisible: !stateBefore.menuVisible,
}));
}
handleOutsideClick(event) {
if (this.node.contains(event.target)) {
return;
}
this.handleClick();
}
render() {
const items =
<div className={'dropdown-items'}>
<button
ref={this.props.refs.Home} onClick={() => this.props.goTo('Home')}
className={(this.props.activeElement === 'Home' ? "active-mobile-page " : "")}>
Home
</button>
<button
ref={this.props.refs.About} onClick={() => this.props.goTo('About')}
className={(this.props.activeElement === 'About' ? "active-mobile-page " : "")}>
About
</button>
<button
ref={this.props.refs.Services} onClick={() => this.props.goTo('Services')}
className={(this.props.activeElement === 'Services' ? "active-mobile-page " : "")}>
Services
</button>
<button
ref={this.props.refs.Projects} onClick={() => this.props.goTo('Projects')}
className={(this.props.activeElement === 'Projects' ? "active-mobile-page " : "")}>
Projects
</button>
<button
ref={this.props.refs.Contact} onClick={() => this.props.goTo('Contact')}
className={(this.props.activeElement === 'Contact' ? "active-mobile-page " : "")}>
Contact
</button>
</div>;
return (
<div className={'dropdown-menu' + (this.state.menuVisible ? ' dropdown-menu-open' : '')}
ref={node => this.node = node}>
<button className={'hamburger hamburger--elastic' + (this.state.menuVisible ? ' is-active' : '')} onClick={this.handleClick} type={'button'}>
<span className="hamburger-box">
<span className={'hamburger-inner' + (this.state.menuVisible || this.props.sticky ? ' hamburger-inner-sticky' : '')}>
</span>
</span>
</button>
{this.state.menuVisible ? items : undefined}
</div>
);
}
}
当然,一切都被 <ScrollNavigation elements={{Home: {}, About: {}, Services: {}, Projects: {}, Contact: {}}}>...</ScrollNavigation>
包装起来,如 react-single-page-navigation 的文档所述。
我决定是显示移动导航还是桌面导航 css 以及以下 class:
import React, {Component} from 'react';
import MobileNavigation from "./mobileNavigation";
import DesktopNavigation from "./desktopNavigation";
export default class Navigation extends Component {
render() {
return (
<div>
<MobileNavigation
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.isSticky}/>
<DesktopNavigation
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.isSticky}/>
</div>
);
}
}
我希望这些信息足够了。我不喜欢 post 我的整个项目,但我认为这是没有必要的。桌面导航按预期工作。移动导航仅在主页部分导航毫米。我认为有一个基本的反应“东西”导致了我无法弄清楚的行为,因为当我取消注释除了渲染方法之外的所有东西时移动导航工作(以及调用未注释的东西的渲染方法中的东西;)) .
如果您需要更多信息或有其他问题,请提问! :)
提前致谢,节日快乐!
马克西莫图斯
好的,所以我的错误是将滚动导航 ref={this.props.refs.Home}
(等)的引用放到了按钮上。我不知何故误解了 instructions in the docs of react-single-page-navigation。 ref 属性就像 'anchor' 所以滚动导航知道滚动到哪里。我将这个 ref 添加到按钮本身,所以导航只是滚动到按钮的位置。
所以我只是将它从按钮中删除,现在一切正常(桌面导航也一样,我知道为什么它以前在那里工作但出现同样的错误)。
<ul className='navbar--link'>
<div onClick={() => this.props.goTo('Home')}>
<div
className={(this.props.activeElement === 'Home' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Home
</div>
</div>
<div onClick={() => this.props.goTo('About')}>
<div
className={(this.props.activeElement === 'About' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
About
</div>
</div>
<div onClick={() => this.props.goTo('Services')}>
<div
className={(this.props.activeElement === 'Services' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Services
</div>
</div>
<div onClick={() => this.props.goTo('Projects')}>
<div
className={(this.props.activeElement === 'Projects' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Projects
</div>
</div>
<div onClick={() => this.props.goTo('Contact')}>
<div
className={(this.props.activeElement === 'Contact' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Contact
</div>
</div>
</ul>
现在,滚动导航的触发器只定义了 goTo 属性,而 ref 属性由我网站的部分定义。