将功能传递给props.children

时间:2020-03-11 16:18:25

标签: reactjs react-props

我已经研究了无数堆栈溢出问题来解决此问题,但是似乎没有一个对我有用。可能是我不了解某些内容,但是我遵循解决方案是什么,但仍然得到我遇到的错误或更严重的错误。

我在这里有布局组件:

FIRAuthErrorUserInfoUpdatedCredentialKey

现在,当我加载页面时,但是在控制台中却出现此错误:

    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;

有人可以帮助我理解为什么其他答案/教程说要使用React.Clone方法并将函数传递给它,但它对我不起作用,然后这些功能在子代上不可用。

1 个答案:

答案 0 :(得分:0)

您正在尝试通过克隆子代将道具handleErrors添加到<div className={classes.gridContainer}>

如果要将此道具添加到AgGridReact组件中,请删除div。