如何使用React滚动到div onClick?

时间:2019-01-17 22:47:36

标签: javascript reactjs react-native

我正在使用React构建的这个应用程序中有一个粘性导航。我要弄清楚的是如何使用onClick滚动到该div?我正在使用window.scrollTo方法。

页面上的div具有对应于锚标记的ID。

handleClick = e => {
    this.setState({
        activeSection: e.target.id,
    });
    let sections = document.querySelectorAll('.deal-details__container');

    window.scrollTo({
        top: 690,
        behavior: 'smooth',
    });
};

我的标记如下:

<h6 className="section-header-overview text-center mb-0">
<a href="#overview" className={ this.state.activeSection === true ? 'active' : ''} onClick={() => this.handleClick('overview')}>
    Overview
</a>

这里是我需要滚动到的组件之一:

import React from 'react';
import { dealType } from '../../../../core/types';
import SpecsGroup from './SpecsGroup';
import SpecsTabButton from './SpecsTabButton';
import { Row, Col, Container } from 'reactstrap';
import { groupBy, filter, map, toPairs, pipe, prop, zipObj } from 'ramda';



export default class Specs extends React.PureComponent {
    scrollRef = React.createRef();

    static propTypes = {
        deal: dealType.isRequired,
    };

    state = {
        activeTab: 'capabilities',
        activeCategory: null,
    };

    filterSpecs() {
        const groupByCategories = pipe(
            filter(item => {
                if (
                    this.state.activeTab === 'capabilities' &&
                    capabilitiesCategories.includes(item.category)
                ) {
                    return true;
                }

                if (
                    this.state.activeTab === 'features' &&
                    featuresCategories.includes(item.category)
                ) {
                    return true;
                }

                return false;
            }),
            groupBy(prop('category')),
            toPairs,
            map(zipObj(['category', 'values']))
        );


    return groupByCategories(this.props.deal.equipment);
}

toggleActiveTab(tab) {
    if (this.state.activeTab !== tab) {
        this.setState({
            activeTab: tab,
            activeCategory: null,
        });
    }
}

toggleActiveCategory(category) {
    if (this.state.activeCategory !== category) {
        this.setState({
            activeCategory: category,
        });
    } else {
        this.setState({
            activeCategory: null,
        });
    }
}

render() {
    if (
        !this.props.deal.equipment ||
        this.props.deal.equipment.length === 0
    ) {
        return false;
    }

    return (
        <div className="deal-details__container pt-5 pb-5" id="specs" ref={this.scrollRef}>
            <Container>
                <Row className="deal__section-heading" noGutters>
                    <Col>
                        <h3 className="text-center"> Specifications </h3>
                    </Col>
                </Row>
                <Row className="rounded bg-white shadow-sm" noGutters>
                    <Col>
                        <Row className="deal-details__specs-tabs" noGutters>
                            <SpecsTabButton
                                isActive={
                                    this.state.activeTab === 'capabilities'
                                }
                                label="Capabilities"
                                value="capabilities"
                                handleOnClick={this.toggleActiveTab.bind(
                                    this
                                )}
                            />
                            <SpecsTabButton
                                isActive={
                                    this.state.activeTab === 'features'
                                }
                                label="Features"
                                value="features"
                                handleOnClick={this.toggleActiveTab.bind(
                                    this
                                )}
                            />
                        </Row>
                        <SpecsGroup
                            deal={this.props.deal}
                            category={this.state.activeTab}
                            activeCategory={this.state.activeCategory}
                            specs={this.filterSpecs()}
                            toggleActiveCategory={this.toggleActiveCategory.bind(
                                this
                            )}
                        />
                    </Col>
                </Row>
            </Container>
        </div>
    );
}
 }

我仍在学习React和JS。因此,我这样做可能完全错误。我读过关于裁判的文章,但不确定是否会更好/更糟。

任何帮助,我们将不胜感激!

3 个答案:

答案 0 :(得分:2)

您可以使用React的ref系统,该系统使您可以访问DOM elements and manipulation.

因此,在您的代码中,您可以执行以下操作:

class myComponent extends React.Component{
    constructor(props){
       super(props)
       this.state = {
          field: value
       }
       //creates a reference for your element to use
       this.myDivToFocus = React.createRef()
    }

    handleOnClick = (event) => {
        //.current is verification that your element has rendered
        if(this.myDivToFocus.current){
            this.myDivToFocus.current.scrollIntoView({ 
               behavior: "smooth", 
               block: "nearest"
            })
        }
    }

    render(){
       return(
          <button onClick={this.handleOnClick}>Click me</button>
          <div ref={this.myDivToFocus}>
              Welcome to my section
          </div>

       )
    }

}

答案 1 :(得分:0)

我对this library有一定的经验,并喜欢使用它,值得一看

答案 2 :(得分:0)

如果引用是针对在触发 OnClick 事件的父容器中存在的类组件,您需要将引用作为道具传递给子组件。然后,在组件的主 div 中使用 'ref' 属性。