Reactjs 向道具传递函数

Reactjs 向道具传递函数,reactjs,react-props,Reactjs,React Props,为了解决这个问题,我研究了无数的堆栈溢出问题,但没有一个适合我。可能是我不理解某些东西,但我遵循解决方案,但仍然会出现错误或更严重的错误 我在这里有我的布局组件: import React, { useState, useEffect, Fragment } from "react"; // Sentry import * as Sentry from '@sentry/browser'; // Material UI import CloseIcon from '@material

为了解决这个问题,我研究了无数的堆栈溢出问题,但没有一个适合我。可能是我不理解某些东西,但我遵循解决方案,但仍然会出现错误或更严重的错误

我在这里有我的布局组件:

    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;
当我在子元素上抛出错误时,它也会出错。以下是我的子元素之一:

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方法并将函数传递给它,但它对我不起作用,而且这些函数在子对象上也不可用。

您正试图通过克隆子对象将prop
handleErrors
添加到


如果你想将这个道具添加到你的
AgGridReact
组件中,请删除div.

那么你的意思是我不能添加这个道具并在效果中使用它吗?不,我是说
不是有效的Dom元素哦,好的,我明白了。我不想把这个函数传递给任何元素。我只需要传递到组件中使用的函数将在divisionView.js中挂载部分useEffect
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