Передача функций в props.children - PullRequest
0 голосов
/ 11 марта 2020

Я посмотрел на бесчисленные вопросы переполнения стека, чтобы решить эту проблему, но ни один из них, похоже, не работает для меня. Может быть, я чего-то не понимаю, но я слежу за тем, какие есть решения, и все равно получаю ошибку, которая у меня есть, или ошибки хуже.

У меня есть компонент макета здесь:

    import React, { useState, useEffect, Fragment } from "react";

// Sentry
import * as Sentry from '@sentry/browser';

// Material UI
import CloseIcon from '@material-ui/icons/Close';
import Snackbar from '@material-ui/core/Snackbar';
import { makeStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';

// Components
import NavBar from "./../components/NavBar";

const useStyles = makeStyles(theme => ({
    root: {
        display: 'flex',
        flex: 1,
        flexDirection: 'column',
    },
    main: {
        display: 'flex',
        flex: 1,
        flexDirection: 'row',
    },
}));

function MainLayout(props) {
    const classes = useStyles();
    const [snackBarOpen, setSnackBarOpen] = useState(false);
    const [snackBarMessage, setSnackBarMessage] = useState(null);

    const handleErrors = (error, message) => {
        setSnackBarMessage(message)
        setSnackBarOpen(true)

        Sentry.captureMessage(error)
    }

    const handleSnackBarClose = () => {
        setSnackBarOpen(false);
    }

    const children = React.cloneElement(
        React.Children.only(props.children), {
            handleErrors: handleErrors
        }
    )

    return (
        <div className={classes.root}>
            <NavBar />
            <main className={classes.main}>
                { children }
            </main>
            <Snackbar
                open={snackBarOpen}
                onClose={handleSnackBarClose}
                message={snackBarMessage}
                anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
                action={
                    <Fragment>
                        <IconButton size="small" aria-label="close" color="inherit" onClick={handleSnackBarClose}>
                            <CloseIcon fontSize="small" />
                        </IconButton>
                    </Fragment>
                }
            />
        </div>
    );
  }

  export default MainLayout;

Сейчас когда я загружаю страницу, она загружается, однако у меня появляется эта ошибка в консоли:

*Warning: React does not recognize the `handleErrors` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `handleerrors` instead. If you accidentally passed it from a parent component, remove it from the DOM element.*

Также, когда у меня выдается ошибка на дочернем элементе, он выдает ошибку. Вот один из моих дочерних элементов:

import React, { useState, useEffect, Fragment } from "react";

// Sentry
import * as Sentry from '@sentry/browser';

// AG Grid
import { AgGridReact } from 'ag-grid-react';

// Material UI
import CloseIcon from '@material-ui/icons/Close';
import Snackbar from '@material-ui/core/Snackbar';
import { makeStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';

// Components
import NavBar from "./../components/NavBar";
import { graphQLQuery } from "../utils/queries";
import MainLayout from "./../layouts/MainLayout";
import { mapGridColumns } from "../utils/helper-functions";

// CSS
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';

const useStyles = makeStyles(theme => ({
    root: {
        display: 'flex',
        flex: 1,
        flexDirection: 'column',
    },
    main: {
        display: 'flex',
        flex: 1,
        flexDirection: 'row',
    },
    gridContainer: {
        width: '100%',
        height: '100%',
    }
}));

function DivisionsView(props) {
    const classes = useStyles();
    const [divisions, setDivisions] = useState([]);
    const [agGridRowData, setAgGridRowData] = useState([]);
    const [agGridColumnDefs, setAgGridColumnDefs] = useState([]);

    useEffect(() => {
        async function fetchDivisions() {
            const query = `{
                division {
                  record_id
                  region_id
                  division_id
                  division
                  division_name
                }
              }`;
            let divisionsFetched = await graphQLQuery(query);

            if(divisionsFetched.hasOwnProperty('errors')) {
                props.handleErrors(divisionsFetched.errors, 'There was an error fetching divisions. Please try again in a few minutes.');
            }

            if(divisionsFetched.hasOwnProperty('data')) {
                setDivisions(divisionsFetched.data)
            }
        }

        fetchDivisions();
    }, [])

    useEffect(() => {
        if(divisions.hasOwnProperty('division') && divisions.division.length > 0) {
            let headerNames = mapGridColumns(divisions.division[0]);

            setAgGridColumnDefs(headerNames);
            setAgGridRowData(divisions.division);
        }
    }, [divisions])

    return (
        <MainLayout>
            <div className={classes.gridContainer}>
                <AgGridReact
                    columnDefs={agGridColumnDefs}
                    rowData={agGridRowData}>
                </AgGridReact>
            </div>
        </MainLayout>
    );
  }

  export default DivisionsView;

Когда отображаются следующие ошибки:

TypeError: props.handleErrors is not a function

Может кто-нибудь помочь мне понять, почему другие ответы / учебное пособие говорят использовать React.Clone метод и передать функции в него, но у меня это не работает, а затем функции недоступны для детей.

1 Ответ

0 голосов
/ 11 марта 2020

Вы пытаетесь добавить опору handleErrors к <div className={classes.gridContainer}>, клонируя детей.

Если вы хотите добавить эту опору в ваш AgGridReact компонент, удалите div.

...