微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 react-single-page-navigation 只能在没有构造函数和状态的组件中工作?

如何解决为什么 react-single-page-navigation 只能在没有构造函数和状态的组件中工作?

我目前正在学习 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',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 和以下类显示移动或桌面导航:

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>
        );
    }
}

我希望这是足够的信息。我不喜欢发布我的整个项目,但我认为这没有必要。桌面导航按预期工作。移动导航只是在主页部分导航毫米。我认为有一个基本的反应“东西”导致了我无法弄清楚的行为,因为当我取消对渲染方法(以及渲染方法调用未注释的东西;) 之外的所有内容的注释时,移动导航可以工作.

如果您需要更多信息或有其他问题,请提问! :)

提前致谢,节日快乐!

马克西姆图斯

解决方法

好的,所以我的错误是将滚动导航 ref={this.props.refs.Home}(等)的引用放在按钮上。我以某种方式误解了 instructions in the docs of react-single-page-navigation。 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 属性由我网站的部分定义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。