Как мне добавить AppBar с кнопкой «Вверх» из Material UI для React в моем приложении? - PullRequest
1 голос
/ 03 мая 2020

В документации к Material UI я нашел этот код:

import React from 'react';
import PropTypes from 'prop-types';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import useScrollTrigger from '@material-ui/core/useScrollTrigger';
import Box from '@material-ui/core/Box';
import Container from '@material-ui/core/Container';
import Fab from '@material-ui/core/Fab';
import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
import Zoom from '@material-ui/core/Zoom';

const useStyles = makeStyles((theme) => ({
    root: {
        position: 'fixed',
        bottom: theme.spacing(2),
        right: theme.spacing(2),
    },
}));

function ScrollTop(children) {
    const classes = useStyles();
    const trigger = useScrollTrigger({
        target: window ? window() : undefined,
        disableHysteresis: true,
        threshold: 100
    });

    const handleClick = (event) => {
        const anchor = (event.target.ownerDocument || document).querySelector('#back-to-top-anchor');
        if (anchor) {
            anchor.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    };
    return (<Zoom in={trigger}>
        <div onClick={handleClick} role="presetation" className={classes.root}>
            {children}
        </div>
    </Zoom>);
}
export default function BackToTop(children) {
    return (
        <React.Fragment>
            <CssBaseline />
            <AppBar>
                <Toolbar>
                    <Typography variant="h6">Scroll to see button</Typography>
                </Toolbar>
            </AppBar>
            <Toolbar id="back-to-top-anchor" />
            <Container>
                <Box my={2}>
                    {[...new Array(100)]
                        .map(
                            () => `Cras mattis consectetur purus sit amet fermentum.
                                    Cras justo odio, dapibus ac facilisis in, egestas eget quam.
                                    Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
                                    Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`,
                        )
                        .join('\n')}
                </Box>
            </Container>
            <ScrollTop {...children}>
                <Fab color="secondary" size="small" aria-label="scroll back to top">
                    <KeyboardArrowUpIcon />
                </Fab>
            </ScrollTop>
        </React.Fragment>
    );
}

Было сказано, что этот код является верхней панелью, на которой будет нарисована кнопка Back to top. Но я не понимаю, что я должен передать как children в BackToTop функцию. Может кто-нибудь мне помочь? PS Код также включает в себя контент, который хранится внутри элемента Box, он только для тестирования. Если я понимаю назначение параметра children правильно, у меня должна быть возможность сделать функцию BackToTop независимой от каких-либо параметров.

1 Ответ

1 голос
/ 03 мая 2020

Часть документации, на которую вы ссылаетесь, находится здесь: https://material-ui.com/components/app-bar/#back -вверх . Версия песочницы с кодом этой демонстрации находится здесь: https://codesandbox.io/s/r59zg?file= / demo. js.

Код в вашем вопросе имеет некоторые проблемные c изменения по сравнению с демонстрацией из документация. Смущает, что вы переименовали props в children в нескольких местах (аргумент BackToTop и аргумент ScrollTop). В коде из документации следует отметить, что реквизиты, переданные в BackToTop, никогда не используются - они передаются в ScrollTop через <ScrollTop {...props}>, но ScrollTop также не использует ни один из этих реквизитов. (и поскольку index.js не передает никаких реквизитов BackToTop, это пустой объект, так что не может с ним ничего сделать ).

Вот немного упрощенная версия демонстрации для удаления неиспользуемых реквизитов:

import React from "react";
import PropTypes from "prop-types";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import useScrollTrigger from "@material-ui/core/useScrollTrigger";
import Box from "@material-ui/core/Box";
import Container from "@material-ui/core/Container";
import Fab from "@material-ui/core/Fab";
import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp";
import Zoom from "@material-ui/core/Zoom";

const useStyles = makeStyles(theme => ({
  root: {
    position: "fixed",
    bottom: theme.spacing(2),
    right: theme.spacing(2)
  }
}));

function ScrollTop(props) {
  const { children } = props;
  const classes = useStyles();
  const trigger = useScrollTrigger({
    disableHysteresis: true,
    threshold: 100
  });

  const handleClick = event => {
    const anchor = (event.target.ownerDocument || document).querySelector(
      "#back-to-top-anchor"
    );

    if (anchor) {
      anchor.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  };

  return (
    <Zoom in={trigger}>
      <div onClick={handleClick} role="presentation" className={classes.root}>
        {children}
      </div>
    </Zoom>
  );
}

ScrollTop.propTypes = {
  children: PropTypes.element.isRequired
};

export default function BackToTop() {
  return (
    <React.Fragment>
      <CssBaseline />
      <AppBar>
        <Toolbar>
          <Typography variant="h6">Scroll to see button</Typography>
        </Toolbar>
      </AppBar>
      <Toolbar id="back-to-top-anchor" />
      <Container>
        <Box my={2}>
          {[...new Array(25)]
            .map(
              () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`
            )
            .join("\n")}
        </Box>
      </Container>
      <ScrollTop>
        <Fab color="secondary" size="small" aria-label="scroll back to top">
          <KeyboardArrowUpIcon />
        </Fab>
      </ScrollTop>
    </React.Fragment>
  );
}

Edit Back to top

children, используемый в ScrollTop являются дочерними элементами в JSX в элементе ScrollTop. В данном случае это:

        <Fab color="secondary" size="small" aria-label="scroll back to top">
          <KeyboardArrowUpIcon />
        </Fab>

Передача кнопки с плавающим действием в ScrollTop как показа, когда пользователь прокручивает, и того, что, при нажатии, вызывает страницу чтобы вернуться к началу.

Код в вашем вопросе имеет ScrollTop(children), а не ScrollTop({children}) - т.е. вы вызываете весь props объект children вместо того, чтобы получить children подпирай его.

...