如何在React切换菜单中实现Link to section

时间:2019-10-07 15:12:48

标签: reactjs menu react-router toggle

我正在从React Starter Kit样板开始构建一个单页Web应用程序。我正在尝试实现一个切换菜单,其中每个按钮应滚动到以下部分:https://reactjsexample.com/check-out-the-magic-behind-out-toggle-menu/

我不知道如何实现:

<Link
                activeClass="active"
                to="section1"
                spy={true}
                smooth={true}
                offset={-70}
                duration={500}
              >
                Section 1
</Link>

在用数字硬编码的数组中,该数组不包含对象:

const iconArrayOne = [1, 2, 3];
const iconArrayTwo = [1, 2, 3].reverse();

因此,当单击每个数组变量时(1应该是一个链接,或者通过链接到= section的变量映射),链接将滚动到App.js中列出的部分ID。

      <Section
        title="Section 1"
        subtitle={dummyText}
        dark={true}
        id="section1"
      />

section.js组件:

import React from "react";


export default function Section({ title, subtitle, dark, id }) {
  return (
    <div className={"section" + (dark ? " section-dark" : "")}>
      <div className="section-content" id={id}>
        <h1>{title}</h1>
        <p>{subtitle}</p>
      </div>
    </div>
  );
}

链接到部分,当前正在使用导航菜单:

import React, { Component } from "react";
import logo from "../hamburger.svg";
import { Link, animateScroll as scroll } from "react-scroll";

export default class Navbar extends Component {
  scrollToTop = () => {
    scroll.scrollToTop();
  };

  render() {
    return (
          <nav className="nav Toggle Collapse" id="basic-navbar-nav" expand="" aria-controls="basic-navbar-nav">
            <div className="nav-content">
              <img
                src={logo}
                className="nav-logo"
                alt="Logo"
                onClick={this.scrollToTop}
              />
              <ul className="nav-items">
                <li className="nav-item">
                  <Link
                    activeClass="active"
                    to="section1"
                    spy={true}
                    smooth={true}
                    offset={-70}
                    duration={500}
                  >
                    Section 1
              </Link>
                </li>
                <li className="nav-item">
                  <Link
                    activeClass="active"
                    to="section2"
                    spy={true}
                    smooth={true}
                    offset={-70}
                    duration={500}
                  >
                    Section 2
              </Link>
                </li>
                <li className="nav-item">
                  <Link
                    activeClass="active"
                    to="section3"
                    spy={true}
                    smooth={true}
                    offset={-70}
                    duration={500}
                  >
                    Section 3
              </Link>
                </li>
                <li className="nav-item">
                  <Link
                    activeClass="active"
                    to="section4"
                    spy={true}
                    smooth={true}
                    offset={-70}
                    duration={500}
                  >
                    Section 4
              </Link>
                </li>
                <li className="nav-item">
                  <Link
                    activeClass="active"
                    to="section5"
                    spy={true}
                    smooth={true}
                    offset={-70}
                    duration={500}
                  >
                    Section 5
              </Link>
                </li>
              </ul>
            </div>
          </nav>
 );  
}
}

Buttonmenu.js

import React, { Component } from 'react';
import {Motion, StaggeredMotion, spring} from 'react-motion';
import noop from 'react-props-noop';
import classNames from 'classnames';
import Link from "react-scroll";

/**
 * <Btn />
 */
class Btn extends Component {
  constructor() {
    super();

    this.state = {
      active: false,
    }

    this._onClick = this._onClick.bind(this);
  }

  _onClick() {
    this.setState({ 
      active: !this.state.active 
    });
  }

  render() {
    //const sectionone = <Link to="section1"> Section 1</Link> 
    const iconArrayOne = [1, 2, 3];
    const iconArrayTwo = [1, 2, 3].reverse();
    const tooltipArrayOne = ['One', 'Two', 'Three'];
    const tooltipArrayTwo = ['One', 'Two', 'Three'].reverse();

    return (
      <div className="container">
        <ButtonGroup>
          <StaggeredMotion
            defaultStyles={[
              { x: -45, o: 0 },
              { x: -45, o: 0 },
              { x: -45, o: 0 },
            ]}
            styles={prevInterpolatedStyles => prevInterpolatedStyles.map((_, i) => {
              return i === prevInterpolatedStyles.length - 1
                ? {
                  x: spring(this.state.active ? 0 : -45, { stiffness: 330, damping: 20 }),
                  o: spring(this.state.active ? 1 : 0, { stiffness: 330, damping: 20 }),
                } : {
                  x: spring(prevInterpolatedStyles[i + 1].x, { stiffness: 330, damping: 20 }),
                  o: spring(prevInterpolatedStyles[i + 1].o, { stiffness: 330, damping: 20 }),
                };
            })}
          >
            {interpolatingStyles =>
              <ButtonGroup>
                {interpolatingStyles.map((style, i) =>
                  <Button
                    key={i}
                    style={{
                      position: 'relative',
                      right: style.x,
                      opacity: style.o,
                      pointerEvents: this.state.active ? 'auto' : 'none',
                    }}
                  >
                    <Tooltip text={tooltipArrayOne[i]} />
                    {iconArrayOne[i]}
                 </Button>
                )}
              </ButtonGroup>
            }
          </StaggeredMotion>

          <Motion
            defaultStyle={{ s: 0.675 }}
            style={{ s: spring(this.state.active ? 1 : 0.675, { stiffness: 330, damping: 14 }) }}
          >
            {interpolatingStyles =>
              <Button 
                className="button--large" 
                onClick={this._onClick} 
                style={{ 
                  transform: 'scale(' + interpolatingStyles.s + ')',
                }}
              >
                <span className={this.state.active ? 'icon active' : 'icon'} />
              </Button>
            }
          </Motion>

          <StaggeredMotion
            defaultStyles={[
              { x: -45, o: 0 },
              { x: -45, o: 0 },
              { x: -45, o: 0 },
            ]}
            styles={prevInterpolatedStyles => prevInterpolatedStyles.map((_, i) => {
              return i === 0
                ? {
                  x: spring(this.state.active ? 0 : -45, { stiffness: 330, damping: 20 }),
                  o: spring(this.state.active ? 1 : 0, { stiffness: 330, damping: 20 }),
                } : {
                  x: spring(prevInterpolatedStyles[i - 1].x, { stiffness: 330, damping: 20 }),
                  o: spring(prevInterpolatedStyles[i - 1].o, { stiffness: 330, damping: 20 }),
                };
            })}
          >
            {interpolatingStyles =>
              <ButtonGroup>
                {interpolatingStyles.map((style, i) =>
                  <Button
                    key={i}
                    style={{
                      position: 'relative',
                      left: style.x,
                      opacity: style.o,
                      pointerEvents: this.state.active ? 'auto' : 'none',
                    }}
                  >
                    <Tooltip text={tooltipArrayTwo[i]} />
                    {iconArrayTwo[i]}
                  </Button>
                )}
              </ButtonGroup>
            }
          </StaggeredMotion>
        </ButtonGroup>
      </div>
    );
  }
}

/**
 * <Tooltip />
 */
const Tooltip = (props) => <span className="tooltip">{props.text}</span>;

/**
 * <ButtonGroup />
 */
const ButtonGroup = (props) => <div className="button-group" style={props.style}>{props.children}</div>;

/**
 * <Button />
 */
const Button = (props) => <button className={classNames('button', props.className)} style={props.style} onClick={props.onClick || noop}>{props.children}</button>;

export default Btn;

App.js文件:<Buttonmenu />是我的切换菜单

import React, { Component } from 'react';
import logo from "./hamburger.svg";
import "./App.css";
import Customnavbar from "./components/Customnavbar";
import Section from "./components/Section";
import dummyText from "./DummyText";


import {
  BrowserRouter as Router,
  Route
} from 'react-router-dom';

// components

import Header from './components/headerComponent/header';
import Footer from './components/footerComponent/footer';
import Homepage from './components/pages/homePage';
import Products from './components/pages/products';
import Buttonmenu from "./components/headerComponent/buttonmenu";

// includes

import './Assets/css/default.min.css';

class App extends Component {
  render() {
    return (

      <Router>
        <div className="App">

          <Header />

          <Route exact path='/' component={Homepage} />
          <Route exact path='/Products' component={Products} />
          <Customnavbar />
          <Buttonmenu />
          <Section
            title="Section 1"
            subtitle={dummyText}
            dark={true}
            id="section1"
          />
          <Section
            title="Section 2"
            subtitle={dummyText}
            dark={false}
            id="section2"
          />
          <Section
            title="Section 3"
            subtitle={dummyText}
            dark={true}
            id="section3"
          />
          <Section
            title="Section 4"
            subtitle={dummyText}
            dark={false}
            id="section4"
          />
          <Section
            title="Section 5"
            subtitle={dummyText}
            dark={true}
            id="section5"
          />
          <Footer />
        </div>
      </Router>
    );
  }
}

export default App;

0 个答案:

没有答案