繁体   English   中英

从父组件调用子组件函数给出错误:无法读取未定义的属性

[英]Calling Child Component Function From Parent Component Give Error : Cannot read properties of undefined

我有这样的子组件。

父 => 子父 => 子

我在子组件中有一个函数,我需要在父组件中调用这个函数。为此,我使用 React Hooks。 (我是参考这篇文章做的,因为我是reatjs的新同学。)

这是我的代码。

import React, {forwardRef, useRef, useImperativeHandle} from 'react';
import {Button} from '@material-ui/core';

function Parent(props) {
    const childRef = useRef();
    const addDate = () =>{
        childRef && childRef.current.submitHandler();
    };
    return (
        <div>
            {/* eslint-disable-next-line react/jsx-no-undef */}
            <Button
                onClick={addDate}>
                SAVE
            </Button>
            <SubParent ref={childRef}/>
        </div>
    );
}


function SubParent(props) {
    return (
        <div>
            <Child ref={props.ref}/>
        </div>
    );
}


const Child = forwardRef((props, ref) => {
    const submitHandler = () => {};
    useImperativeHandle(
        ref,
        () => ({
            submitHandler,
        }),
    );

    return (
        <div>Child Component</div>
    );
});

但是当我按下父组件中的按钮时,我有这个错误。

错误图片链接

类型错误:无法读取未定义的属性(读取“submitHandler”)

我找不到我的错误。 如果有人能帮助我解决这个问题,我真的很感激。 非常感谢。❤️

我认为你在正确的轨道上。 但是,只需要转发来自SubParent组件的 ref 否则它将附加到SubParent组件而不是Child组件

这是代码和框: https ://codesandbox.io/s/vigorous-hooks-o5n5s ? file =/ src/App.js:215-780

function Parent(props) {
  const childRef = useRef();
  const addDate = () => {
    childRef && childRef.current.submitHandler();
  };
  return (
    <div>
      <Button onClick={addDate}>SAVE</Button>
      <SubParent ref={childRef} />
    </div>
  );
}

const SubParent = React.forwardRef((props, ref) => ( // check this implementation
  <div>
    <Child ref={ref} />
  </div>
));

const Child = forwardRef((props, ref) => {
  const submitHandler = () => {
    console.log("Called");
  };

  useImperativeHandle(ref, () => ({
    submitHandler
  }));

  return <div>Child Component</div>;
});

您不能从中间SubParent组件中的默认 props 对象转发 ref,因为 ref 不会以这种方式传递。

从将引用转发到 DOM 组件

常规函数或类组件不接收 ref 参数,并且 ref 在 props 中也不可用。

您需要将forwardRef()应用于父级和最终子级之间的每个组件。

 const { forwardRef, useRef, useImperativeHandle } = React; function Parent(props) { const childRef = useRef(); const addDate = () => { childRef && childRef.current.submitHandler(); }; return ( <div> <button onClick={addDate}>SAVE</button> <SubParent ref={childRef} /> </div> ); } const SubParent = forwardRef((props, ref) => { return ( <div> <Child ref={ref} /> </div> ); }); const Child = forwardRef((props, ref) => { const submitHandler = () => { console.log('In submit handler'); }; useImperativeHandle(ref, () => ({ submitHandler })); return <div>Child Component</div>; }); ReactDOM.render(<Parent />, document.getElementById('root'));
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

你几乎做了所有的事情,但只是一点,你需要将forwardRef而不是ref传递到SubParent

import React, { forwardRef, useRef, useImperativeHandle } from "react";
import { Button } from "@material-ui/core";

function Parent(props) {
  const childRef = useRef();
  const addDate = () => {
    console.log("from parent component");
    childRef?.current?.submitHandler();
  };
  return (
    <div>
      <Button onClick={addDate}>SAVE</Button>
      <SubParent forwardRef={childRef} />
    </div>
  );
}

function SubParent(props) {
  return (
    <div>
      <Child ref={props.forwardRef} />
    </div>
  );
}

const Child = forwardRef((props, ref) => {
  const submitHandler = () => {
    console.log("from child component");
  };
  useImperativeHandle(ref, () => ({
    submitHandler: submitHandler
  }));

  return <div>Child Component</div>;
});

export default Parent;

试试codeandbox

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM