javascript 如何使用 React 滚动到 div onClick?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54245395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:22:19  来源:igfitidea点击:

How can I scroll to a div onClick using React?

javascriptreactjsreact-native

提问by Lz430

I have a sticky navigation in this app I'm building using React. What I'm trying to figure out is how can I scroll to that div using an onClick? I'm using the window.scrollTomethod.

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

The divs on the page have corresponding IDs to the anchor tags.

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

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

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

My markup looks like this:

我的标记如下所示:

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

Here is one of the components I need to scroll to:

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

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

I'm still learning react and JS in general. So I may be doing this completely wrong. I've read about refs, but not sure if those would be better/worse.

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

Any and all help is appreciated!

任何和所有的帮助表示赞赏!

回答by Cool Guy

You can use React's ref system which gives you access to DOM elements and manipulation.

你可以使用 React 的 ref 系统,它可以让你访问 DOM elements and manipulation.

So in your code you can do something like this:

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

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>

       )
    }

}